Kotlin 委托


Kotlin 通过引入新关键字的设计模式“by”支持“委托”。使用此关键字或委托方法,Kotlin 允许派生类通过特定对象访问接口的所有已实现公共方法。下面的示例演示了在 Kotlin 中这是如何发生的。

interface Base {
    fun printMe() // 抽象方法
}
class BaseImpl(val x: Int) : Base {
    override fun printMe() { println(x) }   // 方法的实现
}
class Derived(b: Base) : Base by b  // 委托对象 b 上的公共方法

fun main(args: Array<String>) {
    val b = BaseImpl(10)
    Derived(b).printMe() // 打印 10 :: 访问 printMe() 方法
}

在示例中,我们有一个接口“Base”,其抽象方法名为“printme()”。在 BaseImpl 类中,我们正在实现这个“printme()”,然后我们在另一个类中使用“by”关键字来使用这个实现。

上面的代码将在浏览器中产生以下输出。

10

属性委托


在上一节中,我们已经了解了使用“by”关键字的委托设计模式。在本节中,我们将学习使用 Kotlin 库中提到的一些标准方法来进行属性委托。

委托意味着将责任传递给另一个类或方法。当在某些地方已经声明了一个属性,那么我们应该重用相同的代码来初始化它们。在下面的示例中,我们将在我们的示例中实现委托时使用 Kotlin 提供的一些标准委托方法和一些标准库函数。

使用 Lazy()

Lazy 是一个 lambda 函数,它将一个属性作为输入,作为回报给出一个实例懒惰,其中

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 Newbiego.com") {
        prop, old, new ->
        println("$old -> $new")
    }
}
fun main(args: Array<String>) {
    val user = User()
    user.name = "first"
    user.name = "second"
}

上面的代码将在浏览器中产生以下输出。

first -> second

一般来说,语法是“by”关键字被委托后的表达式。这get()set()变量的方法p将委托给其getValue()setValue()Delegate 类中定义的方法。

class 例子 {
    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() 方法。