Kotlin 也支持委托功能,分为
- 类委托
- 属性委托
1. 类委托
类委托的核心思想是将一个类的一些具体实现委托给另一个类去完成,如下代码:
@Test
fun main() {
val baseImpl = BaseImpl()
val myClass = MyCustomerClass(baseImpl)
myClass.baseFun1()
myClass.baseFun2()
myClass.customFun1()
}
interface BaseIFace {
fun baseFun1()
fun baseFun2()
}
class BaseImpl : BaseIFace {
override fun baseFun1() {
println("共有方法1")
}
override fun baseFun2() {
println("共有方法2")
}
}
class MyCustomerClass(private val whateverNameIs: BaseIFace) : BaseIFace by whateverNameIs {
fun customFun1() {
println("个性化方法1")
}
}
by 子句表示,将 baseImpl 保存在 MyCustomerClass 的对象实例内部,而且编译器将会生成继承自 BaseIFace 接口的所有方法, 并将调用转发给 baseImpl。
需要注意的是:
MyCustomerClass 必须实现一个接口,而不能继承于一个类;
whateverNameIs 的类型必须是 BaseIFace 所实现接口的子类型;
使用场景也比较容易从代码中归纳:
有一些公共方法在接口中,如果每次实现该接口都需要覆写这些方法,如果希望覆写的方式统一唯一,那可以建一个代理类实现这个接口,然后在实现该接口的共有方法的时候,指定代理类来替自己做出统一的覆写,可以简化代码结构,同时使覆写方式唯一,如果需要有新的覆写方式,那使用新的代理类就好了
2. 属性委托
属性委托指的是一个类的某个属性值不是在类中直接进行定义,而是将其托付给一个代理类,从而实现对该类的属性统一管理。
属性委托语法格式:
val/var <属性名>: <类型> by <表达式>
var/val:属性类型(可变/只读)
属性名:属性名称
类型:属性的数据类型
表达式:委托代理类
by 关键字之后的表达式就是委托, 属性的 get() 方法(以及set() 方法)将被委托给这个对象的 getValue()和 setValue()方法。属性委托不必实现任何接口, 但必须提供 getValue() 函数(对于 var属性,还需要 setValue() 函数)。
定义一个被委托的类
该类需要包含 getValue() 方法和 setValue() 方法,且参数 thisRef为进行委托的类的对象,property 为进行委托的属性的对象。
写法上,需要严格按照模板代码书写,才可生效:
import kotlin.reflect.KProperty
// 定义包含属性委托的类
class Example {
var p: String by Delegate()
}
// 委托的类
class Delegate {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return "$thisRef, 这里委托了 ${property.name} 属性"
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
println("$thisRef 的 ${property.name} 属性赋值为 $value")
}
}
fun main(args: Array<String>) {
val e = Example()
println(e.p) // 访问该属性,调用 getValue() 函数
e.p = "Runoob" // 调用 setValue() 函数
println(e.p)
}
输出结果为:
Example@433c675d, 这里委托了 p 属性
Example@433c675d 的 p 属性赋值为 Runoob
Example@433c675d, 这里委托了 p 属性