Kotlin 的 by keyword 讓我們可以很輕鬆地實作 Delegation Pattern。首先,先讓我們看一下,一般實作 Delegation Pattern 的程式碼。我們看到 Window.area() 委託呼叫給 bound.area(),就沒有做其他的事情了。當 Shape 的 methods 多的時候,Window 就要實作很多這種的程式碼。
interface Shape {
fun area(): Int
}
class Rectangle(private val width: Int, private val height: Int) : Shape {
override fun area(): Int = width * height
}
class Window(private val bound: Shape) : Shape {
override fun area(): Int = bound.area()
}
fun main() {
val shape = Window(Rectangle(6, 5))
println("area is ${shape.area()}")
}
// Output:
// area is 30當我們使用 Kotlin 的 by keyword 時,我們就不需要再實作這些委託的程式碼。這使得程式碼相當地精簡,如下。
interface Shape {
fun area(): Int
}
class Rectangle(private val width: Int, private val height: Int) : Shape {
override fun area(): Int = width * height
}
class Window(private val bound: Shape) : Shape by bound
fun main() {
val shape = Window(Rectangle(6, 5))
println("area is ${shape.area()}")
}
// Output:
// area is 30by keyword 也允許我們使用自己的實作。
interface Shape {
fun area(): Int
fun printArea()
}
class Rectangle(private val width: Int, private val height: Int) : Shape {
override fun area(): Int = width * height
override fun printArea() {
println("Rectangle area is ${area()}")
}
}
class Window(private val bound: Shape) : Shape by bound {
override fun printArea() {
println("Window area is ${area()}")
}
}
fun main() {
Window(Rectangle(6, 5)).printArea()
}
// Output:
// Window area is 30然而,與繼承不同的是,委託的物件無法呼叫我們自己實作的方法。如下程式碼中,當我們呼叫 Window.printArea() 時,它會委託給 Rectangle.printArea(),然後在其裡面呼叫的會是 Rectangle.area() 而不是 Window.area()。
interface Shape {
fun area(): Int
fun printArea()
}
class Rectangle(private val width: Int, private val height: Int) : Shape {
override fun area(): Int = width * height
override fun printArea() {
println("Rectangle area is ${area()}")
}
}
class Window(private val bound: Shape) : Shape by bound {
override fun area(): Int = bound.area() * 10
}
fun main() {
Window(Rectangle(6, 5)).printArea()
}
// Output:
// Rectangle area is 30









