类代理
interface Base{
fun print()
}
class BaseImpl(val x:Int):Base{
override fun print() {
println(x)
}
}
class Derived(var b:Base):Base by b{
fun printStrong(){
println("1111")
b.print()
println("222222")
}
}
fun main(array: Array<String>) {
val b = BaseImpl(1)
Derived(b).printStrong()
}
在 Derived 的父类列表中的 by 从句会将 b 存储在 Derived 内部对象,并且编译器会生成 Base 的所有方法并转给 b。
代理属性
很多常用属性,虽然我们可以在需要的时候手动实现它们,但更好的办法是一次实现多次使用,并放到库。比如:
延迟属性:只在第一次访问是计算它的值
观察属性:监听者从这获取这个属性更新的通知 在 map 中存储的属性,而不是单独存在分开的字段
class Example{
var p:String by Delegate()
}
class Delegate {
operator fun getValue(example: Example, property: KProperty<*>): String {
println("11111111")
return "333"
}
operator fun setValue(example: Example, property: KProperty<*>, s: String) {
println("2222222")
}
}
属性代理不需要任何接口的实现,但必须要提供 get() 方法(如果是变量还需要 set() 方法)
代理属性的要求
只读属性 (val),代理必须提供一个名字叫 get 的方法并接受如下参数:
接收者--必须是相同的,或者是属性拥有者的子类型
元数据--必须是 PropertyMetadata 或这它的子类型
这个函数必须返回同样的类型作为属性。
可变属性 (var),代理必须添加一个叫 set 的函数并接受如下参数:
接受者--与 get() 一样 元数据--与 get() 一样 新值--必须和属性类型一致或是它的字类型
标准代理
kotlin.properties.Delegates 对象是标准库提供的一个工厂方法并提供了很多有用的代理
网友评论