Skip to content

what is delegation in kotlin

Devrath edited this page Feb 27, 2024 · 26 revisions

In Kotlin, delegation is a design pattern that allows one class to use the functionalities of another class by delegating some of its responsibilities to the delegated class. This is achieved using the by keyword in Kotlin.

By using delegation, a class can reuse code from another class without directly inheriting from it. This promotes code reuse and composition over inheritance, which can lead to more flexible and maintainable code.

Here's a simple example to illustrate delegation in Kotlin:

Code

interface Printer {
    fun printMessage(message: String)
}

class BasicPrinter : Printer {
    override fun printMessage(message: String) {
        println("BasicPrinter: $message")
    }
}

class DecoratedPrinter(printer: Printer) : Printer by printer

fun main() {
    val basicPrinter = BasicPrinter()
    val decoratedPrinter = DecoratedPrinter(basicPrinter)

    decoratedPrinter.printMessage("Hello, Kotlin!")
}

Output

BasicPrinter: Hello, Kotlin!

In this example, BasicPrinter is a class that implements the Printer interface. DecoratedPrinter is another class that also implements the Printer interface but delegates the printMessage function to an instance of Printer passed in its constructor. This means that DecoratedPrinter does not contain the actual implementation of printMessage but relies on the delegated Printer instance to perform the printing.

When you create an instance of DecoratedPrinter and call its printMessage function, it uses the implementation from the BasicPrinter class.

Delegation allows you to compose objects and build more modular and reusable components in your code.

Property Delegation

In Kotlin, property delegation is a powerful feature that allows you to delegate the implementation of property access and modification to another object, known as the delegate. This helps in achieving code reuse, separation of concerns, and cleaner code.

To use property delegation, you define a property by using the by keyword, followed by an instance of a delegate class. The delegate class must have a specific structure, providing implementations for at least the getValue and optionally the setValue functions.

Here's a simple example using a built-in delegate by lazy:

class Example {
    val lazyValue: String by lazy {
        println("Computed!")
        "Hello"
    }
}

fun main() {
    val example = Example()
    println(example.lazyValue) // Prints "Computed!" and then "Hello"
    println(example.lazyValue) // Only prints "Hello" as the value is already computed and cached
}

In this example, the lazy delegate is used to compute the value of lazyValue lazily, meaning it's computed only when it is first accessed.

You can also create custom delegates by implementing the ReadOnlyProperty or ReadWriteProperty interface. Here's a simple custom delegate example:

import kotlin.reflect.KProperty

class CustomDelegate : ReadOnlyProperty<Any, String> {
    override fun getValue(thisRef: Any, property: KProperty<*>): String {
        return "Custom Value"
    }
}

class Example {
    val customValue: String by CustomDelegate()
}

fun main() {
    val example = Example()
    println(example.customValue) // Prints "Custom Value"
}

In this case, CustomDelegate implements the ReadOnlyProperty interface, and its getValue method provides the custom logic for accessing the property.

Property delegation in Kotlin provides a flexible way to customize property behavior, making the code more modular and readable.

Clone this wiki locally