Background:
The "Delegation" pattern is known in many OOP languages, it is the principle of passing work from one object to another. In Java, delegation is implemented manually — through an internal field and proxying methods. In Kotlin, delegation is brought to the syntax level using the by keyword.
Problem:
Implementing the delegation pattern in Java leads to "God" proxy classes that are overloaded with boilerplate code and incur high maintenance costs for the interface. It is challenging to maintain interface contract updates and change delegates.
Solution:
Kotlin allows you to create classes that implement an interface not directly, but by delegating all of its methods to another object using the notation class Foo(...) : MyInterface by delegateObj. This allows for writing concise and understandable code, eliminating boilerplate without losing flexibility.
Code example:
interface Base { fun print() } class BaseImpl(val x: Int) : Base { override fun print() = println(x) } class Derived(b: Base) : Base by b fun main() { Derived(BaseImpl(42)).print() // 42 }
Key features:
Can a declaring class change the behavior of a specific method despite delegation?
Yes — if the interface method is implemented explicitly in the delegating class (Derived), it will "override" the delegated behavior for that specific method.
Example:
class Derived(b: Base) : Base by b { override fun print() = println("Overrided!") }
Is it possible to delegate multiple interfaces to different objects at once?
No, in Kotlin, you cannot directly delegate multiple different interfaces to different objects in one declaration. You would need to write a class with manual delegation or combine inheritance and delegation, if the architecture allows it.
Does delegation work with abstract classes or only with interfaces?
Delegation is only possible with interfaces, not with abstract classes — because abstract classes can have states and protected methods that are incompatible with delegation declaration using by.
A developer manually implements the delegation pattern for a dozen methods of a large interface. When extending the interface, they forget to add new proxy methods. The code grows, and bugs multiply.
Pros:
Cons:
The by syntax is used for automatic interface delegation. Easy to change implementations and swap delegates on the fly without risking errors during contract maintenance.
Pros:
Cons: