Kotlin 委托

249 阅读1分钟

委托

类委托

by 表示

interface  Base {
    val message: String
    fun  print()
}

class BaseImpl(val x: Int): Base {

    override val message: String
        get() = "BaseImpl"

    override fun print() {
        println(message)
    }
}

class Derived(b: Base): Base by b {

    override val message: String
        get() = "Derived"

    override fun print() {
        println(message)
    }
}

fun main() {
    val base = BaseImpl(10)
    Derived(base).print()

    println(Derived(base).message)
}

委托属性的声明

1.定义一个委托属性的语法是 val/var <property name>: <Type> by <expression>,其中 by 后面的就是属性的委托。属性委托不用继承什么特别的接口,只要拥有用 operator 修饰的 getValue()setValue() (适用 var)的函数就可以了 2.val/var <属性名>: <类型> by <表达式>

  • var/val:属性类型(可变/只读)
  • 属性名:属性名称
  • 类型:属性的数据类型
  • 表达式:委托代理类
// 定义包含属性委托的类
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)
}

延迟属性 Lazy

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

val lazyV: String by lazy {

    println("init")

    "hello World"
}

fun main() {
    println(lazyV)
    println(lazyV)
}

// init
hello World
hello World

可观察属性 Observable

1.当属性值改变的时候运行函数方法

2.Delegates.observable() 接受两个参数:初始值和修改时处理程序(handler)。 每当我们给属性赋值时会调用该处理程序(在赋值后执行)。它有三个参数:被赋值的属性、旧值和新值

class User {
    var name: String by Delegates.observable("init") {
        property, oldValue, newValue ->
        println("$oldValue -> $newValue")
    }
}

fun main() {
    val user = User()
    user.name = "aa"
}

把属性储存在映射中

class User(val map: Map<String, Any?>) {
    val name: String by map
    val age: Int     by map
}
val user = User(mapOf(
    "name" to "John Doe",
    "age"  to 25
))