委派属性

有一些特定类型的属性尽管我们每次可以手动的书写,但是如果有一种很好的方式来实现一次,并且在所有类似的情况下都适用并被加入标准库,这将很有益处。这样的例子可以是下列的情况:

  • 懒加载属性:属性会在第一次访问时计算值
  • 可观察属性:属性变化时的接口回调通知
  • 存储在Map中的属性,而不是为每个属性创建一个字段

为了覆盖这种情况的使用,Kotlin支持委派属性

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

定义委派属性的语法形式为:

val/var <property name>: <Type> by <expression>

by之后的表达式就是委派,因为属性的gettersetter方法会被委派给其getValuesetValue方法。属性委派类不需要实现任何接口,但是必须提供getValue方法(对于var属性还需要提供setValue方法)。

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.'")
    }
}

在上述的例子中,当我们读取p时将会委派给Delegate的实例,DelegategetValue方法将会被调用,因此其第一个参数就是包含p属性的那个对象,第二个参数就是p属性的描述(比如属性的名字)。

val e = Example()
println(e.p)

将会打印出:

com.android.mykotlin.Example@3a71f4dd, thank you for delegating 'p' to me!

类似地,当我们给p赋值,setValue方法将会执行。前两个参数与getValue方法一致,第三个参数是待赋的值。

e.p = "NEW"

将会打印出:

NEW has been assigned to 'p in com.android.mykotlin.Example@3a71f4dd.'

成为委派对象的条件请查看下面的内容。

从Kotlin 1.1开始你可以声明委派属性在函数或代码块中,而不是必须要在成员变量中,下面的内容有相关示例。

results matching ""

    No results matching ""