Language Elements

Data Types

Kotlin Classes

Kotlin Operators

Kotlin Null Safety

Extension Functions

Kotlin Functional

Lambda Functions

Object Oriented Kotlin

Data Classes

Coroutines

Collections

Delegation

Lateinit and Lazy Initialization

Scope Functions

Kotlin Key Words

Kotlin Example Codes

Kotlin Interview Questions

Kotlin Tutorial

Delegation in Kotlin

Delegation in Kotlin lets an object outsource behavior to another object, favoring composition over inheritance.

Delegation vs Inheritance

Inheritance Delegation
Relationship IS-A (vertical hierarchy) HAS-A / USES-A (horizontal association)
Best suited for Modeling type hierarchies with shared core logic Sharing behavior across unrelated types
Usage in Kotlin open class, override for subclassing by keyword for interface and property delegation

Key Features

How Delegation Works in Kotlin

Interface Delegation with by

Kotlin enables interface delegation using the by keyword, allowing a class to delegate interface implementation to another instance.

interface Logger {
    fun log(message: String)
}

class ConsoleLogger : Logger {
    override fun log(message: String) = println("Log: $message")
}

class Service(logger: Logger) : Logger by logger {
    fun performTask() {
        log("Task performed") // Delegated call
    }
}

fun main() {
    val service = Service(ConsoleLogger())
    service.performTask() // Output: Log: Task performed
}

Without Delegation: Manual Forwarding

Without the by keyword, you must manually forward each interface method:

class ServiceWithoutDelegation(private val logger: Logger) : Logger {
    override fun log(message: String) = logger.log(message) // Manual forwarding

    fun performTask() {
        log("Task performed")
    }
}

Kotlin's delegation eliminates this boilerplate while maintaining type safety.

Property Delegation in Kotlin

Built-in Delegates

Kotlin provides several standard property delegates:

// Lazy initialization
val lazyValue: String by lazy {
    println("Computed!")
    "Hello"
}

fun main() {
    println(lazyValue) // Prints "Computed!" then "Hello"
    println(lazyValue) // Only prints "Hello"
}
// Observable properties
import kotlin.properties.Delegates

var name: String by Delegates.observable("initial") { _, old, new ->
    println("Changed from $old to $new")
}

fun main() {
    name = "first"  // Prints: Changed from initial to first
    name = "second" // Prints: Changed from first to second
}

Custom Property Delegates

Create custom delegates by implementing getValue and setValue:

import kotlin.reflect.KProperty

class UpperCaseDelegate {
    private var value: String = ""

    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return value.uppercase()
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        this.value = value
    }
}

class Example {
    var text: String by UpperCaseDelegate()
}

fun main() {
    val example = Example()
    example.text = "delegation"
    println(example.text) // Output: DELEGATION
}


Copyright © by Zafar Yasin. All rights reserved.