目录
- 类委托
- 属性委托 2.1. 方法一:可以按需继承
ReadOnlyProperty、ReadWriteProperty
两个接口中的一个; 2.2. 方法二:自己定义,但方法参数必须和 1 中接口的方法参数一致; - 标准委托 3.1. 延迟属性 Lazy 3.2. 可观察属性 Observable 3.3. 把属性储存在映射中
- 使用场景
类委托(代理模式)
类的两种代理方法
interface Base { fun print()}class BaseImpl(val x: Int) : Base { override fun print() { print(x) }}// 第一种:这里直接使用关键字 by 进行代理class Derived(base: Base) : Base by base// 第二种:class Derived(base: Base) : Base { val base : Base init { this.base = base } override fun print() { base.print() // base是BaseImpl的实例对象 }}// 测试class Main { fun main() { val b = BaseImpl(10) Derived(b).print() // prints 10 }}复制代码
属性委托
语法结构: val/var <property name>: <Type> by <expression>
两种实现方法:
-
方法一:可以按需继承
ReadOnlyProperty、ReadWriteProperty
两个接口中的一个;// 读取属性public interface ReadOnlyProperty
{ public operator fun getValue(thisRef: R, property: KProperty<*>): T}// 读写属性public interface ReadWriteProperty { // 关键字 operator 重载操作符 public operator fun getValue(thisRef: R, property: KProperty<*>): T public operator fun setValue(thisRef: R, property: KProperty<*>, value: T)}复制代码 示例代码:
class Delegate
: ReadWriteProperty { // 重写了getValue()方法 override fun getValue(thisRef: Any?, property: KProperty<*>): T { return ... } override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { } }class Main { var p: String by Delegate () fun test() { val main = Main() print(main.p) // 会调用到Delegate中的getValue()方法 main.p = "Elson" // 会调用到Delegate中的setValue()方法 }}复制代码 -
方法二:自己定义,但方法参数必须和 1 中接口的方法参数一致;
class Delegate
{ // 使用关键字 operator 来实现重载 operator fun getValue(thisRef: Any?, property: KProperty<*>): T { return "$thisRef, thank you for delegating '${property.name}' to me!" } operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { println("$value has been assigned to '${property.name}' in $thisRef.") }}复制代码 示例代码:
class Main { var p: String by Delegate
() //属性 p 被代理 fun test() { val main = Main() print(main.p) // 会调用到Delegate中的getValue()方法 main.p = "Elson" // 会调用到Delegate中的setValue()方法 }}复制代码
标准委托
1. 延迟属性 Lazy
-
示例代码:
val lazyValue: String by lazy { println("computed!") "Hello"}fun main(args: Array
) { println(lazyValue) //第一次调用lazyValue时,会先初始化lazy{}作用区间的代码,即打印一个"computed!",然后返回一个"Hello"字符串并赋值给lazyValue; println(lazyValue) //第二次调用lazyValue时,直接将"Hello"赋值给lazyValue;可参考下面的源码}复制代码 -
源码:
Lazy.kt
文件public fun
lazy(initializer: () -> T): Lazy = SynchronizedLazyImpl(initializer)private object UNINITIALIZED_VALUE@JvmVersionprivate class SynchronizedLazyImpl (initializer: () -> T, lock: Any? = null) : Lazy , Serializable { private var initializer: (() -> T)? = initializer @Volatile private var _value: Any? = UNINITIALIZED_VALUE // final field is required to enable safe publication of constructed instance private val lock = lock ?: this override val value: T get() { val _v1 = _value if (_v1 !== UNINITIALIZED_VALUE) { @Suppress("UNCHECKED_CAST") return _v1 as T //第二次执行操作时,这里直接返回对象 } return synchronized(lock) { val _v2 = _value if (_v2 !== UNINITIALIZED_VALUE) { @Suppress("UNCHECKED_CAST") (_v2 as T) } else { val typedValue = initializer!!()//第一次使用时执行这里,将lazy大括号内的代码进行初始化,并返回最后一行的数据并赋值给typedValue _value = typedValue initializer = null typedValue } } } override fun isInitialized(): Boolean = _value !== UNINITIALIZED_VALUE override fun toString(): String = if (isInitialized()) value.toString() else "Lazy value not initialized yet." private fun writeReplace(): Any = InitializedLazyImpl(value)}复制代码
2. 可观察属性 Observable
示例代码:
class User { // 方法一: var name: String by Delegates.observable("") { prop, old, new -> println("$old -> $new") } // 方法二:Delegates.observable()实际上就是对ObservableProperty的一层封装 var name : String by object : ObservableProperty (" ") { override fun afterChange(property: KProperty<*>, oldValue: String, newValue: String) { println("$oldValue -> $newValue") } }}fun main() { val user = User() user.name = "first" user.name = "second"}复制代码
输出结果 < no name > -> first first -> second
源码:
public inline funobservable(initialValue: T, crossinline onChange: (property: KProperty<*>, oldValue: T, newValue: T) -> Unit): ReadWriteProperty = object : ObservableProperty (initialValue) { override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) = onChange(property, oldValue, newValue)}public inline fun vetoable(initialValue: T, crossinline onChange: (property: KProperty<*>, oldValue: T, newValue: T) -> Boolean): ReadWriteProperty = object : ObservableProperty (initialValue) { // 需要返回一个boolean值,判断是否需要发射,默认为true override fun beforeChange(property: KProperty<*>, oldValue: T, newValue: T): Boolean = onChange(property, oldValue, newValue)}public abstract class ObservableProperty (initialValue: T) : ReadWriteProperty { private var value = initialValue protected open fun beforeChange(property: KProperty<*>, oldValue: T, newValue: T): Boolean = true protected open fun afterChange (property: KProperty<*>, oldValue: T, newValue: T): Unit {} // 代理后,自动被调用 public override fun getValue(thisRef: Any?, property: KProperty<*>): T { return value } // 代理后,自动被调用 public override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { val oldValue = this.value // 判断是否需要发射,默认为true if (!beforeChange(property, oldValue, value)) { return } this.value = value afterChange(property, oldValue, value) }}复制代码
3. 把属性储存在映射中
这部分不知道怎么看源码
class User(val map: Map) { val name: String by map val age: Int by map}val user = User(mapOf( "name" to "John Doe", "age" to 25))复制代码