Kotlin's delegation pattern is a fundamental principle where an object delegates its functionality to another object. Kotlin supports delegation both at the class level (by delegating interfaces) and at the property level. This pattern is in line with the principle of composition over inheritance, offering a flexible alternative to inheriting behavior from a superclass.

Class Delegation

Kotlin allows class delegation using the by keyword. When a class implements an interface, it can delegate the implementation of its methods to another object.

Example of Class Delegation:


interface Base {
    fun print()
}

class BaseImpl(val x: Int) : Base {
    override fun print() { print(x) }
}

class Derived(b: Base) : Base by b

fun main() {
    val b = BaseImpl(10)
    Derived(b).print() // Outputs 10
}


In this example, Derived class doesn't implement the print method itself but delegates it to an instance of BaseImpl. When you call print on an instance of Derived, it internally calls print on the BaseImpl instance it holds.

Property Delegation

Kotlin supports property delegation, where a property's getter and setter can be delegated to a separate object, known as a delegate. The delegate is responsible for getting and setting the value. Property delegation is useful for encapsulating common patterns of property use, such as lazy initialization, observable properties, or storing properties in a map.

Example of Property Delegation:


import kotlin.reflect.KProperty

class Delegate {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return "$thisRef, thank you for delegating '${property.name}' to me!"
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("$value has been assigned to '${property.name}' in $thisRef.")
    }
}

class Example {
    var p: String by Delegate()
}

fun main() {
    val e = Example()
    println(e.p) // Calls getValue, which constructs a string

    e.p = "NEW" // Calls setValue, which prints a message
}


In this property delegation example, the p property of the Example class is delegated to an instance of Delegate. Whenever p is accessed (getter) or modified (setter), the corresponding getValue or setValue method of Delegate is called.

Benefits of Delegation in Kotlin

Kotlin's support for delegation simplifies many programming tasks and encourages composing objects in a way that promotes reusability and flexibility.