Skip to content
Kotlin

Delegation

Delegate interfaces, lazy properties, observables, and custom delegates.

#delegation#delegate

Code

kotlin
import kotlin.properties.Delegates

// Interface delegation
interface Logger {
    fun log(msg: String)
}

class ConsoleLogger : Logger {
    override fun log(msg: String) = println("[log] $msg")
}

// by delegates the Logger implementation
class Service(logger: Logger) : Logger by logger {
    fun run() {
        log("starting")
        println("working")
        log("done")
    }
}

Service(ConsoleLogger()).run()

// Property delegation: lazy
val heavy: String by lazy {
    println("computing")
    "result"
}
println("before")
println(heavy)
println(heavy)

// Delegated property with observable
var count by Delegates.observable(0) { _, old, new ->
    println("count: $old -> $new")
}
count = 1
count = 2

// Custom delegate
class Validator<T>(private val check: (T) -> Boolean) {
    private var value: T? = null
    operator fun getValue(thisRef: Any?, prop: kotlin.reflect.KProperty<*>): T =
        value ?: throw IllegalStateException("not set")
    operator fun setValue(thisRef: Any?, prop: kotlin.reflect.KProperty<*>, value: T) {
        require(check(value)) { "validation failed" }
        this.value = value
    }
}

class Form {
    var age: Int by Validator { it in 0..130 }
}

val f = Form()
f.age = 25
println(f.age)
// f.age = 200  // throws IllegalArgumentException