Kotlin:Delegation Pattern 和 by 關鍵字

Photo by Celine Ylmz on Unsplash
Photo by Celine Ylmz on Unsplash
Kotlin 的 by keyword 讓我們可以很輕鬆地實作 Delegation Pattern。當我們使用 kotlin 的 by keyword 時,我們就不需要再實作這些委託的程式碼。這使得程式碼相當地精簡。

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 30

by 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
發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

You May Also Like
Photo by Hans-Jurgen Mager on Unsplash
Read More

Kotlin Coroutine 教學

Kotlin 的 coroutine 是用來取代 thread。它不會阻塞 thread,而且還可以被取消。Coroutine core 會幫你管理 thread 的數量,讓你不需要自行管理,這也可以避免不小心建立過多的 thread。
Read More