Kotlin学习4.7:委托
- 类委托
- 属性委托
- 延时加载
委托模式也叫代理模式,是最常用的一种设计模式。
在委托模式中,如果有两个对象参与与处理同一个请求,则接受请求的对象将请求委托给另一个对象来处理,简单来说A的工作交给B来做。
委托模式是实现继承的一个很好的替代方式。
委托是通过 by 关键字实现的,并且主要分为两种形式,一种是类委托,一种是属性委托。
类委托
大家知道委托是有两个对象完成的,因此可以推测出类委托实际上也包含两个对象,一个是委托类,一个是被委托类。
在委托类中并没有真正的功能方法,该类的功能是通过调用被委托类中的方法实现的。
示例代码如下。
interface Wash{
fun washDishes()
}
class Child : Wash{
override fun washDishes() {
println("child is washing")
}
}
class Parent : Wash by Child(){}
fun main() {
var parent = Parent()
parent.washDishes()
}
实际上类委托还有一种写法,就是在委托类继承接口的同时,传入一个被委托类的实例对象。
实例代码如下。
interface Wash{
fun washDishes()
}
class Child : Wash{
override fun washDishes() {
println("child is washing")
}
}
class Parent(washer: Wash) : Wash by washer
fun main() {
var child = Child()
Parent(child).washDishes()
}
属性委托
除了类委托之外,Kotlin还支持属性委托,属性委托是指一个类的某个属性值不是在类中直接定义,而是将其委托给一个代理类,从而实现对该类的属性进行统一的管理。
语法格式如下。
val/var <属性名>: <类型> by <表达式>
举一个生活中的委托实例,在过年时,小朋友会把自己的压岁钱交给父母来保管,这就是委托。
示例代码如下。
import kotlin.reflect.KProperty
class Parent(){
var money: Int = 0
operator fun getValue(child: Child, property: KProperty<*>): Int{
println("getValue()方法被调用,修改属性:${property.name}")
return money
}
operator fun setValue(child: Child, property: KProperty<*>, value: Int){
println("getValue()方法被调用,修改属性:${property.name}、" + "属性值:${value}")
money = value
}
}
class Child{
var money: Int by Parent()
}
fun main() {
val child = Child()
println("(1)父母给孩子100元压岁钱")
child.money = 100
println("(2)买玩具花了50")
child.money -= 50
println("(3)自己还有${child.money}")
}
延时加载
在Kotlin中,声明变量或者属性的同时要对其进行初始化,否则就会报异常,尽管我们可以定义可空类型的变量,但有时却不想这样做,能不能在使用变量时再进行初始化呢?
为此,Kotlin中提供了延迟加载,又成懒加载,当变量被访问时才会被初始化,这样不仅可以提高程序效率,还可以让程序启动更快。
延迟加载是通过 by lazy 关键字表示的,延迟加载的变量要求声明为val,即不可变变量,相当于Java中用 final 关键字修饰的变量。
延迟加载也是委托的一种形,延迟加载的语法结构如下。
val/var 变量:变量类型 by lazy{
变量初始化代码
}
需要注意,延迟加载的变量在第一次初始化时会输出代码块中的所有内容,之后再调用该变量时,都只会输出最后一行代码的内容。
延迟加载的具体代码如下。
fun main() {
val content by lazy {
println("Hello")
"World"
}
println(content)
println(content)
}