Kotlin supports two types of delegation: Implementation by delegation and property delegation. This talk explores what the delegation pattern is and means in object oriented programming and how the programming language Kotlin supports it.
other structural design patterns like the proxy, adapter or composition patterns. Plays nicely with dependency injection. Helps breaking down big classes.
private final int height; public Rectangle(int width, int height) { this.width = width; this.height = height; } public int area() { return width * height; } } https://en.wikipedia.org/wiki/Delegation_pattern public class Square { private final Rectangle rectangle; public Square(int side) { this.rectangle = new Rectangle(side, side); } public int area() { return rectangle.area(); } }
return square.side * square.side; } } https://en.wikipedia.org/wiki/Delegation_(object-oriented_programming) public static class Square { private final int side; private final Area area; public Square(int side) { this.side = side; this.area = new Area(); } public int area() { return area.area(this); } }
val height: Int ) { fun area(): Int = width * height } class Square(side: Int) { private val rectangle = Rectangle(side, side) fun area(): Int = rectangle.area() } https://kotlinlang.org/docs/reference/delegation.html
val height: Int ) { fun area(): Int = width * height } class Square(side: Int) { private val rectangle = Rectangle(side, side) fun area(): Int = rectangle.area() } interface Shape { fun area(): Int }
val height: Int ) : Shape { override fun area(): Int = width * height } class Square(side: Int) { private val rectangle = Rectangle(side, side) fun area(): Int = rectangle.area() } interface Shape { fun area(): Int }
val height: Int ) : Shape { override fun area(): Int = width * height } class Square(side: Int) : Shape { private val rectangle = Rectangle(side, side) override fun area(): Int = rectangle.area() } interface Shape { fun area(): Int }
val height: Int ) : Shape { override fun area(): Int = width * height } class Square(side: Int) : Shape by Rectangle(side, side) interface Shape { fun area(): Int }
val height: Int ) : Shape { override fun area(): Int = width * height } class Square(side: Int) : Shape by Rectangle(side, side) { override fun area(): Int = 0 } interface Shape { fun area(): Int }
Delegates.observable(side) { property, oldValue, newValue -> println("Side changed from $oldValue to $newValue") } override fun area(): Int = side * side }
{ operator fun getValue(thisRef: R, property: KProperty<*>): T } // Use for var interface ReadWriteProperty<in R, T> { operator fun getValue(thisRef: R, property: KProperty<*>): T operator fun setValue(thisRef: R, property: KProperty<*>, value: T) }
val defaultValue: T ) : ReadWriteProperty<Activity, T>, InstanceStateProperty { private var value = defaultValue private var key: String? = null private var savedInstanceState: Bundle? = null }
val defaultValue: T ) : ReadWriteProperty<Activity, T>, InstanceStateProperty { private var value = defaultValue final override fun getValue(thisRef: Activity, property: KProperty<*>): T { initializeValue(thisRef, property) return value } final override fun setValue(thisRef: Activity, property: KProperty<*>, value: T) { initializeValue(thisRef, property) this.value = value } }
T> { return when (defaultValue) { is Int -> IntInstanceStateProperty(defaultValue) is String -> StringInstanceStateProperty(defaultValue) else -> throw NotImplementedError("Missing implementation...") } as ReadWriteProperty<Activity, T> }
{ operator fun getValue(thisRef: R, property: KProperty<*>): T } // Use for var interface ReadWriteProperty<in R, T> { operator fun getValue(thisRef: R, property: KProperty<*>): T operator fun setValue(thisRef: R, property: KProperty<*>, value: T) }
KProperty<*> ): V = when (V::class) { String::class -> this.getString(property.name) Int::class -> this.getInt(property.name) else -> throw NotImplementedError("Missing for ${V::class}") } as V