[学习]拥抱kotlin(六)

2021-02-10  本文已影响0人  吴敬悦

今天看委托模式。
有一篇讲得不错的: 一文彻底搞懂Kotlin中的委托
还有中文官网的教程: 委托属性
还有一篇官方的教程: Kotlin Vocabulary | Kotlin 委托代理

刚开始是不知道这是啥的,像下面的代码:

private val viewmodel: LiveDataViewModel by viewModels { LiveDataVMFactory }

我最看不懂的就是 by ,一头雾水,不知道这里是啥含义,于是便开启了我的学习之旅。
看语法形式:

val/var <属性名>: <类型> by <表达式>

在 by 后面的表达式是该 委托, 因为属性对应的 get()(与 set())会被委托给它的 getValue() 与 setValue() 方法。 属性的委托不必实现任何的接口,但是需要提供一个 getValue() 函数(与 setValue()——对于 var 属性)。

看例子:

import kotlin.reflect.KProperty

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.")
    }
}
class Test {
    var name: String by Delegate()
}
fun main(args: Array<String>) {
    val test = Test()
    test.name = "100"
    println(test.name)
}
// 输出:
// 100 has been assigned to 'name' in Test@72ea2f77.
// Test@72ea2f77, thank you for delegating 'name' to me!

可以看到要想委托需要实现对应的方法 getValuesetValue 。其中的参数要求:

其中 thisRef 指的是类,在上面的例子中我编写的是 Any ,所以不受限制,如果我写的是 Int ,那么这里就会失败:

当thisRef不正确时会出现错误
可以看出这里需要的是 TestTest 的超类,当然可以直接写 Any 。既然超类是可以的,那么下面也是可行的:
class Delegate {
    operator fun getValue(thisRef: SupperTest?, property: KProperty<*>): String {
        return "$thisRef, thank you for delegating '${property.name}' to me!"
    }

    operator fun setValue(thisRef: SupperTest?, property: KProperty<*>, value: String) {
        println("$value has been assigned to '${property.name}' in $thisRef.")
    }
}
open class SupperTest
class Test: SupperTest() {
    var name: String by Delegate()
}
上一篇 下一篇

猜你喜欢

热点阅读