委托是一种设计模式,字面意思是我们会委托别人去完成某件事情,在程序中对应的就是操作对象不会去处理某段逻辑,而是会委托给另外一个辅助对象去处理。
委托类
核心思想是将一个类的具体实现交给另一个类去完成。
Set是一个接口,如果需要使用它的话,就需要使用它具体的实现类,比如HashSet。而借助于委托模式,我们可以轻松实现一个自己的实现类。
class MySet<T>(val helperSet:HashSet<T>):Set<T>{
override val size: Int
get() = helperSet.size
override fun contains(element: T)=helperSet.contains(element)
override fun containsAll(elements: Collection<T>)=helperSet.containsAll(elements)
override fun isEmpty()=helperSet.isEmpty()
override fun iterator()=helperSet.iterator()
}
MySet的构造函数中接收了一个HashSet参数,它就相当于与一个辅助对象,Set接口中的所有待实现的方法,我们都没有自己进行实现,而是调用辅助对象中相应的方法去实现,这就是一种委托模式。但是当接口中有大量待实现的方法,我们的工作量会非常大,在Kotlin中可以通过委托类的功能来解决,只需要一个小小的by关键字。
class MySet<T>(val helperSet:HashSet<T>):Set<T> by helperSet{
}
在上面对的代码中,我们在接口的声明后面加上by关键字和受委托的对象,就可以免去我们手动让辅助对象去实现接口中待实现的方法。
另外如果我们需要对某个方法进行重写实现,只需要重写那一个方法就可以了,其它方法不会受到影响,仍可以享受by关键字带来的便利。
委托属性
顾名思义就是将某个属性的具体实现委托给另一个类去完成。
委托属性的语法结构如下
class MyClass{
var p by Delegate()
}
我们使用by关键字连接了左边的p属性和右边的委托类,意思就是将p属性的具体实现委托给了Delegate方法。当我们调用p属性的时候会自动调用Delegate类的getValue()方法,当给p属性赋值的时候会自动调用Delegate类的setValue方法。所以我们需要对Delegate类进行具体的实现,实现模板如下
class Delegaet{
//必须实现getValue和setValue,需要使用operator关键在进行声明
var propValue:Any?=null
//参数1:表示该类的委托功能可以在什么类中使用,参数2:可用于获取各种属性相关的值
operator fun getValue(myClass:Myclass,prop:KProperty<*>):Any?{
return propValue
}
//参数1:表示该类的委托功能可以在什么类中使用,参数2:可用于获取各种属性相关的值,参数3:具体要赋值给委托属性的值
operator fun setValue(myClass:Myclass,prop: KProperty<*>,value:Any?){
propValue=value
}
}