Chapter 14: Delegation

Delegation — this is one of the most loved and most powerful features of Kotlin! ☕✨

Delegation is the feature that makes Kotlin feel like magic when you want to reuse code without writing tons of boilerplate. It’s so clean and expressive that once you start using it, you’ll wonder how you ever lived without it.

We’re going to cover two main kinds of delegation:

  1. Class delegation (by keyword for classes/interfaces)
  2. Delegated properties (by lazy, by observable, by vetoable, and custom delegates)

I’m going to explain everything very slowly and clearly, like we’re sitting together in a Bandra café — with real-life analogies, complete runnable examples, step-by-step breakdowns, tables, common mistakes with fixes, and tons of practical code you can copy-paste and run right now.

Let’s dive in!

1. Class Delegation – The “by” Keyword for Classes & Interfaces

Class delegation lets a class automatically forward all calls to an interface (or another class) to a delegate object you provide — without writing any implementation code yourself!

Real-life analogy: You want to run a restaurant. Instead of learning how to cook everything yourself, you hire a master chef (delegate). You just say: “Whatever customer asks for from the menu (interface), give it to the chef to cook.” → You become the owner (class) but delegate all cooking work to the chef.

Syntax:

Kotlin

Example 1 – Basic class delegation

Kotlin

Output:

text

Key points:

  • by printer → all methods of Printer are automatically forwarded to printer
  • You can still add your own methods (saveAndPrint)
  • You can override any delegated method if you want

Example 2 – Overriding one method

Kotlin

Output:

text

2. Delegated Properties – by lazy, observable, vetoable & Custom Delegates

Delegated properties let you delegate the getter/setter logic of a property to another object — no need to write custom getters/setters manually.

Kotlin provides several built-in delegates — the most famous ones are:

Delegate Type Syntax When to use Key Feature
lazy by lazy { … } Initialize only when first accessed Thread-safe, computed once
observable by observable(initial, handler) Get notified when value changes React to property changes
vetoable by vetoable(initial, handler) Control whether a new value is accepted Validate before setting
Custom delegate by MyDelegate() Create your own logic Full control

A. by lazy – The Most Popular One

Lazy initialization → value is computed only once when first accessed.

Kotlin

Output:

text

Very common use cases:

  • Expensive initialization (database connection, heavy object)
  • Thread-safe by default (synchronized)

B. by observable – React to Changes

Kotlin

Output:

text

C. by vetoable – Validate Before Setting

Kotlin

4. Custom Delegates – Full Power

You can create your own delegate class!

Kotlin

Quick Recap Table (Your Cheat Sheet)

Feature Kotlin Way (Best Practice) Key Benefit
Class delegation class MyList : List by delegate Reuse implementation without boilerplate
Delegated properties – lazy val heavy: Expensive by lazy { … } Lazy init, computed once, thread-safe
Delegated properties – observable var name by Delegates.observable(…) { … } React to changes
Delegated properties – vetoable var temp by Delegates.vetoable(…) { … } Validate before setting
Custom delegate Implement getValue & setValue Full control over property behavior

Common Newbie Mistakes & Fixes

Mistake Problem Fix
Forgetting by keyword Compile error Always write by delegate or by lazy {}
Using val with observable/vetoable Compile error (they need setter) Use var
Not using override in delegated methods Compile error override is still required
Creating heavy object in lazy without thread-safety Race conditions lazy is thread-safe by default
Forgetting to import Delegates Cannot find observable, vetoable import kotlin.properties.Delegates

Homework for You (Let’s Make It Fun!)

  1. Basic Create a data class User(val id: Int, val name: String) → use copy() to create a version with changed name.
  2. Medium Create a class SmartList<T> : MutableList<T> by ArrayList<T>() → add a method fun printSize().
  3. Advanced Create a property var temperature: Double by Delegates.vetoable(0.0) that rejects values below -273.15.
  4. Fun Create object Settings with lazy-loaded val apiKey: String.
  5. Challenge Create a custom delegate that logs every get/set operation for a property.

You’ve just mastered Kotlin’s delegation superpowers — now your code can reuse logic without boilerplate and react to changes beautifully!

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *