What & How: Delegation (Class-Level)

In Kotlin, delegation is a design pattern that allows a class to hand over (delegate) specific tasks or functionalities to another class or object. This means instead of re-implementing methods or duplicating logic, we can reuse existing implementations by delegating responsibilities.

Kotlin provides built-in support for class-level delegation using the by keyword. It encourages the principle of composition over inheritance, resulting in more flexible and reusable designs without creating deep inheritance hierarchies.

Why Use Delegation?

Syntax


interface Printer {
    fun printMessage()
}

class ConsolePrinter : Printer {
    override fun printMessage() {
        println("Printing from ConsolePrinter")
    }
}

// Class-level delegation
class DelegatedPrinter(printer: Printer) : Printer by printer

fun main() {
    val printer = ConsolePrinter()
    val delegatedPrinter = DelegatedPrinter(printer)
    delegatedPrinter.printMessage() // Delegates call to ConsolePrinter
}
  

Explanation

When delegatedPrinter.printMessage() is called, the actual method execution is performed by the ConsolePrinter instance.

Overriding Delegated Methods

Even though a class delegates functionality, it can still override delegated methods to extend or modify the delegated behavior.


class CustomPrinter(printer: Printer) : Printer by printer {
    override fun printMessage() {
        println("Custom behavior before delegating...")
        printer.printMessage()
    }
}

fun main() {
    val printer = ConsolePrinter()
    val custom = CustomPrinter(printer)
    custom.printMessage()
}
  

This approach allows you to combine delegation with method overriding for partial customization.

Real-World Example

Delegation is used widely in the Kotlin standard library and Android development, for example in property delegates like by lazy or Delegates.observable.


import kotlin.properties.Delegates

class User {
    var name: String by Delegates.observable("Unknown") { _, old, new ->
        println("Name changed from $old to $new")
    }
}

fun main() {
    val user = User()
    user.name = "Talha"
    user.name = "Usman"
}
  

Summary

In short: Delegation in Kotlin makes your code reusable, flexible, and less dependent on inheritance, encouraging better composition-based architecture.