83.Kotlin 委托 by

https://www.jianshu.com/p/a70ba6436e75/
https://www.jianshu.com/p/306bdc2bac3f
代理模式:为其他对象提供一种代理以控制其他对象对这个对象的访问。

委托属性的声明

定义一个委托属性的语法是 val/var : by ,其中 by 后面的就是属性的委托。属性委托不用继承什么特别的接口,只要拥有用 operator 修饰的 getValue() 和 setValue() (适用 var)的函数就可以了。

by lazy的必须用val修饰

类委托

一个类中定义的方法实际是调用另一个类的对象的方法来实现的。

//创建接口
interface Base {   
    fun print()
}
//实现此接口的被委托的类
class BaseImpl(val x: Int) : Base {
    override fun print() { print(x) }
}
//通过关键字 by 建立委托类
class Derived(b: Base) : Base by b
//测试
fun main(args: Array) {
    val b = BaseImpl(10)
    Derived(b).print() // 输出 10
}

在 Derived 声明中,by 子句表示,将 b 保存在 Derived 的对象实例内部,而且编译器将会生成继承自 Base 接口的所有方法, 并将调用转发给 b。

属性委托

属性委托是指一个类的某个属性值不是在类中直接进行定义,而是将其托付给一个代理类,从而实现对该类的属性统一管理。
val/var 变量名:类型 by 表达式
by字之后的表达式就是委托,属性的get set方法将被委托给这个对象的setVaule getValue方法,属性委托不必实现任何接口,但必须提供getValue setValue函数。

import kotlin.reflect.KProperty
// 定义包含属性委托的类
class Example {
    var p: String by Delegate()
}
// 委托的类
class Delegate {
    //setValue getValue方法的修饰符 方法名 参数类型 只能这么写
    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) {
    val e = Example()
    println(e.p)     // 访问该属性,调用 getValue() 函数

    e.p = "Runoob"   // 调用 setValue() 函数
    println(e.p)
}
输出结果为:
Example@433c675d, 这里委托了 p 属性
Example@433c675d 的 p 属性赋值为 Runoob
Example@433c675d, 这里委托了 p 属性

标准委托

Kotlin的标准库中已经内置了很多工厂方法来实现属性委托。

延迟属性lazy

lazy()是一个函数,接受一个lambda表达式作为参数,返回一个lazy实例的函数,返回的实例可以作为实现延迟属性的委托:第一次调用get方法会执行已传递给lazy的lambda表达式并记录结果,后续调用get方法只是返回记录的结果。

val lazyValue: String by lazy {
    println("computed!")     // 第一次调用输出,第二次调用不执行
    "Hello"
}
fun main(args: Array) {
    println(lazyValue)   // 第一次执行,执行两次输出表达式
    println("--------")
    println(lazyValue)   // 第二次执行,只输出返回值
}
执行输出结果:
computed!
Hello
--------
Hello

get方法是线程不安全的,lazy是线程安全的,
。。。后面还一个例子看文章。

你可能感兴趣的:(83.Kotlin 委托 by)