# Delegation: by lazy and Class Delegation — Kotlin

Source: https://www.skillbyai.com/en/kotlin/o-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.

```kotlin
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.

**Quiz:** What does `val x by lazy { compute() }` do?

- [x] 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.
