Kotlin - 委託



Kotlin 透過引入新的關鍵字“by”來支援“委託”設計模式。使用此關鍵字或委託方法,Kotlin 允許派生類透過特定物件訪問介面的所有已實現的公共方法。以下示例演示了 Kotlin 中是如何實現的。

interface Base {
   fun printMe() //abstract method
}
class BaseImpl(val x: Int) : Base {
   override fun printMe() { println(x) }   //implementation of the method
}
class Derived(b: Base) : Base by b  // delegating the public method on the object b

fun main(args: Array<String>) {
   val b = BaseImpl(10)
   Derived(b).printMe() // prints 10 :: accessing the printMe() method 
}

在這個例子中,我們有一個名為“Base”的介面,它有一個名為“printme()”的抽象方法。“BaseImpl”類實現了這個“printme()”方法,之後另一個類使用“by”關鍵字使用了這個實現。

以上程式碼將在瀏覽器中產生以下輸出。

10

屬性委託

在上一節中,我們學習了使用“by”關鍵字的委託設計模式。在本節中,我們將學習使用 Kotlin 庫中提到的某些標準方法進行屬性委託。

委託意味著將責任傳遞給另一個類或方法。當某個地方已經聲明瞭一個屬性時,我們應該重用相同的程式碼來初始化它們。在下面的示例中,我們將使用 Kotlin 提供的一些標準委託方法和一些標準庫函式來在我們的示例中實現委託。

使用 Lazy()

Lazy 是一個 lambda 函式,它將屬性作為輸入,並返回一個Lazy<T>的例項,其中<T>基本上是它正在使用的屬性的型別。讓我們來看下面的例子來了解它是如何工作的。

val myVar: String by lazy {
   "Hello"
}
fun main(args: Array<String>) {
   println(myVar +" My dear friend")
}

在上面的程式碼中,我們將變數“myVar”傳遞給 Lazy 函式,該函式依次將值賦給它的物件,並將相同的值返回給主函式。以下是瀏覽器中的輸出。

Hello My dear friend

Delegetion.Observable()

Observable() 接受兩個引數來初始化物件,並將相同的值返回給呼叫的函式。在下面的示例中,我們將看到如何使用 Observable() 方法來實現委託。

import kotlin.properties.Delegates
class User {
   var name: String by Delegates.observable("Welcome to Tutorialspoint.com") {
      prop, old, new ->
      println("$old -> $new")
   }
}
fun main(args: Array<String>) {
   val user = User()
   user.name = "first"
   user.name = "second"
}

以上程式碼將在瀏覽器中產生以下輸出。

first -> second

通常, “by”關鍵字後的表示式是委託的表示式。變數pget()set()方法將委託給在 Delegate 類中定義的getValue()setValue()方法。

class Example {
   var p: String by Delegate()
}

對於上面的程式碼,我們需要生成以下委託類才能為變數p賦值。

class Delegate {
   operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
      return "$thisRef, thank you for delegating '${property.name}' to me!"
   }
   operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
      println("$value has been assigned to '${property.name} in $thisRef.'")
   }
}

讀取時將呼叫 getValue() 方法,設定變數時將呼叫 setValue() 方法。

廣告