पाठ 15 / 25
Delegation: by lazy and Class Delegation
Reuse behaviour with the by keyword.
Delegated properties and interfaces
Delegated properties hand their get and set logic to another object with by. by lazy { ... } computes the value on first access and caches it; by default it is synchronised, so the initialiser runs once across threads. Delegates.observable runs a callback on change, and a property can delegate to a map. Class delegation class LoggingList(inner: MutableList<T>) : MutableList<T> by inner implements an interface by forwarding all calls to another object, letting you override only what you need. It is built-in support for the decorator pattern and favours composition over inheritance.
Lazy values and a counting decorator
Two uses of by.
import kotlin.properties.Delegates
class Report(private val rows: List<String>) {
val summary: String by lazy { // computed once, on first access
rows.joinToString(separator = ", ")
}
var status: String by Delegates.observable("new") { _, old, new ->
println("status $old -> $new")
}
}
class CountingSet<T>(private val inner: MutableSet<T> = HashSet()) : MutableSet<T> by inner {
var attempted = 0
private set
override fun add(element: T): Boolean { // override one method, delegate the rest
attempted++
return inner.add(element)
}
}lazy versus lateinit
Use by lazy for a val you can compute yourself on first use. Use lateinit var when something else, such as a framework or a test setup, assigns the value later.
त्वरित जाँच: What does `val x by lazy { compute() }` do?
- Calls compute() on first access and caches the result
- Calls compute() on every access
- Calls compute() in a background thread at startup
- Makes x nullable
Answer
Calls compute() on first access and caches the result — lazy initialises once and reuses the value.