Skip to content
Kotlin

Delegation

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

By EZ4Code Team
delegationdelegate

Code

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

Explanation

Interface delegation via by lets a class forward interface methods to another object, enabling composition over inheritance. Property delegates like lazy and Delegates.observable intercept get and set to add behavior. Custom delegates implement getValue and setValue operators to encapsulate reusable property logic such as validation or persistence.

More Kotlin Snippets