概述
所谓委托模式 ,就是为其他对象提供一种代理以控制对这个对象的访问,在Java开发过程中,是继承模式之外的很好的解决问题的方案,不熟悉委托模式的,可以参考博委托模式。
对于Kotlin而言,其直接支持委托模式,从而避免为了实现模式而不得不写那些常规的代码。又不得不赞叹,Kotlin的优雅,简洁。
by
Kotlin中,委托的实现依靠于关键字 by ,by表示将抽象主题的实例(by后边的实例)保存在代理类实例的内部,比如SportsManager类继承于ISports接口,并可以ISports接口的所有的 public 方法委托给一个指定的对象。
interface ISports {
fun doSports()
}
class SwimForSports: ISports{
override fun doSports() {
println("do swim")
}
}
class SportsManager(sport: ISports): ISports by sport
fun main(args: Array<String>) {
val swimSports: SwimForSports = SwimForSports()
SportsManager(swimSports).doSports()// Log:do swim
}
在SportsManager声明中,by子句表示,将sport保存在SportsManager的对象实例内部,而且编译器将会生成继承自 ISports 接口的所有方法, 并将调用转发给sport。
委托属性
概述
所谓的委托属性,就是对其属性值的操作不再依赖于其自身的getter()/setter()方法,是将其托付给一个代理类,从而每个使用类中的该属性可以通过代理类统一管理,再也不用在每个类中,对其声明重复的操作方法。
当我们使用属性的get或者set的时候,属性委托的getValue和setValue就会被调用。
定义语法
定义语法:
val/var <property name>: <Type> by <expression>
- var/val:属性类型(可变/只读)
- name:属性名称
- Type:属性的数据类型
- expression:代理类
by关键字之后的表达式就是委托,属性的get()方法(以及set() 方法)将被委托给这个对象的 getValue()和setValue()方法.属性委托不必实现任何接口, 但必须提供 getValue() 函数(对于 var属性,还需要 setValue() 函数)。
使用场景
- 延迟加载属性(lazy property): 属性值只在初次访问时才会计算,
- 可观察属性(observable property): 属性发生变化时, 可以向监听器发送通知,
- 将多个属性保存在一个 map 内, 而不是保存在多个独立的域内.
标准类库
Kotlin标准库中,已经自定义了一系列标准委托,包括了大部分有用的委托。
延迟加载(Lazy)
lazy()是一个函数, 接受一个Lambda表达式作为参数, 返回一个Lazy类型的实例,这个实例可以作为一个委托, 实现延迟加载属性(lazy property): 第一次调用 get() 时, 将会执行 lazy() 函数受到的Lambda 表达式,然后会记住这次执行的结果, 以后所有对 get() 的调用都只会简单地返回以前记住的结果.
// File: test.k