How to Use by Keyword for Delegation in Kotlin
In Kotlin, the
by keyword is used for delegation to automatically forward interface implementation to another object. You declare a class that implements an interface and use by followed by an instance of a class that already implements that interface, so Kotlin handles method calls for you.Syntax
The by keyword is used in a class declaration to delegate the implementation of an interface to another object. The syntax is:
class ClassName(param: InterfaceType) : InterfaceType by param
Here:
ClassNameis your new class.InterfaceTypeis the interface you want to implement.paramis an instance of a class that already implementsInterfaceType.- Kotlin forwards all interface calls to
param.
kotlin
interface Printer {
fun print()
}
class ConsolePrinter : Printer {
override fun print() {
println("Printing to console")
}
}
class DelegatingPrinter(printer: Printer) : Printer by printerExample
This example shows how a class DelegatingPrinter delegates the print method to an instance of ConsolePrinter using the by keyword.
kotlin
interface Printer {
fun print()
}
class ConsolePrinter : Printer {
override fun print() {
println("Printing to console")
}
}
class DelegatingPrinter(printer: Printer) : Printer by printer
fun main() {
val consolePrinter = ConsolePrinter()
val delegatingPrinter = DelegatingPrinter(consolePrinter)
delegatingPrinter.print() // Delegated call
}Output
Printing to console
Common Pitfalls
Common mistakes when using by delegation include:
- Trying to delegate to a null object (delegation target must not be null).
- Expecting to override delegated methods without explicitly doing so in the delegating class.
- Delegating multiple interfaces without handling method name conflicts.
Remember, if you want to customize behavior, you can override delegated methods in your class.
kotlin
interface Printer {
fun print()
}
class ConsolePrinter : Printer {
override fun print() {
println("Console printing")
}
}
// Wrong: delegating to null
// class BadPrinter(printer: Printer?) : Printer by printer // Error: 'printer' can be null
// Correct: non-null delegation
class GoodPrinter(private val printer: Printer) : Printer by printer {
override fun print() {
println("Custom print before delegation")
printer.print() // Now accessible because 'printer' is a property
}
}
// To fix above, keep a reference:
class BetterPrinter(private val printer: Printer) : Printer by printer {
override fun print() {
println("Custom print before delegation")
printer.print()
}
}Quick Reference
Delegation with by keyword cheat sheet:
class MyClass(obj: Interface) : Interface by obj— delegates all interface calls toobj.- Delegation target must be non-null.
- You can override delegated methods to customize behavior.
- Useful for code reuse and composition.
Key Takeaways
Use the
by keyword to delegate interface implementation to another object easily.Delegation target must be a non-null instance implementing the interface.
Override delegated methods in your class to customize behavior if needed.
Delegation helps reduce boilerplate and promotes composition over inheritance.