package cn.zms.class2
import kotlin.properties.Delegates
import kotlin.reflect.KProperty
/**
* 类代理:by关键字
* 属性代理:val/var <property name>: <Type> by <expression>
*/
interface Base{
fun print()
}
class BaseImpl(var x: Int) : Base{
override fun print(){
println(x)
}
}
//类代理,通过“by”关键字,将“b”实例存储到Derived对象中,编译器会生成“Base”接口的所有方法,使用“b”的实现。
class Derived(b: Base) : Base by b
//属性代理
class Example {
//语法:val/var <property name>: <Type> by <expression>
var p: String by DelegateTheP()
}
class DelegateTheP {
//属性代理不需要实现任何接口,只需要提供getValue() setValue()【val属性不需要】函数
/**
* thisRef p所属的Example实例
* property p实例本身的描述信息
*/
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return "$thisRef, thank you for delegating '${property.name}' to me!"
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
println("$value has been assigned to '${property.name} in $thisRef.'")
}
}
class UserPropertyByDelegate(val map: Map<String, Any?>) {
val name: String by map
val age: Int by map
}
class UserPropertyByDelegate2(val map: MutableMap<String, Any?>) {
//var的属性代理,请使用MutableMap对象
var name: String by map
var age: Int by map
}
fun main(args: Array<String>) {
//======================1.类代理======================
val b = BaseImpl(10)
Derived(b).print()
//======================2.属性代理======================
val e = Example()
//读取p访问DelegateTheP.getValue()
println(e.p)
//p的赋值会调用DelegateTheP.setValue()
e.p = "123"
//======================标准属性代理之:Lazy======================
/**
* 默认Lazy属性是线程同步的(synchronized),
* 如果不需要synchronized可以将lazy()构造函数中传入LazyThreadSafetyMode.PUBLICATION,那么多个线程可以同时赋值
* 如果可以确保属性只会在单线程中初始化,可以lazy()构造函数中传入LazyThreadSafetyMode.NONE,以节省线程开销
*/
val lazyValue : String by lazy(){
//第一次访问,初始化,然后保存,相当于单例模式
println("Completed")
"Hello"
}
//只有第一次打印才会
println(lazyValue)
println(lazyValue)
//======================标准属性代理之:Observable======================
//两个参数,初始化的值<no name>,修改值时的回调函数大括号中
var name: String by Delegates.observable("<no name>") {
prop, old, new ->
println("$old -> $new")
}
name = "first"
name = "second"
println(name)
//当需要拦截修改事件,并只能判断是否允许修改,可以使用vetoable代理
var nameVeto: String by Delegates.vetoable("<no nameVeto>") {
prop, old, new ->
println("$old -> $new")
//要有返回值,代表是否允许修改,当second赋值时才能修改
new == "second"
}
nameVeto = "first"
println(nameVeto)
nameVeto = "second"
println(nameVeto)
//======================标准属性代理之:Storing Properties in a Map======================
/**
* 你肯定会经常使用使用Map来存储属性,常见的场景是当需要解析JSON值或其他动态的事情。
* 这时就可以使用Map对象为代理属性提供代理
*/
var user = UserPropertyByDelegate(mapOf(
"name" to "john",
"age" to 15
))
println("${user.name} age is ${user.age}")
//======================3.局部变量代理(since 1.1)======================
//局部变量同样也可以使用代理
}
Kotlin之代理
最新推荐文章于 2023-10-02 08:00:00 发布