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)
}
}
class Derived(b: Base) : Base by b
class Example {
var p: String by DelegateTheP()
}
class DelegateTheP {
/**
* 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 name: String by map
var age: Int by map
}
fun main(args: Array<String>) {
val b = BaseImpl(
10)
Derived(b).print()
val e = Example()
println(e.p)
e.p =
"123"
/**
* 默认Lazy属性是线程同步的(synchronized),
* 如果不需要synchronized可以将lazy()构造函数中传入LazyThreadSafetyMode.PUBLICATION,那么多个线程可以同时赋值
* 如果可以确保属性只会在单线程中初始化,可以lazy()构造函数中传入LazyThreadSafetyMode.NONE,以节省线程开销
*/
val lazyValue : String by lazy(){
println(
"Completed")
"Hello"
}
println(lazyValue)
println(lazyValue)
var name: String by Delegates.observable(
"<no name>") {
prop, old,
new ->
println(
"$old -> $new")
}
name =
"first"
name =
"second"
println(name)
var nameVeto: String by Delegates.vetoable(
"<no nameVeto>") {
prop, old,
new ->
println(
"$old -> $new")
new ==
"second"
}
nameVeto =
"first"
println(nameVeto)
nameVeto =
"second"
println(nameVeto)
/**
* 你肯定会经常使用使用Map来存储属性,常见的场景是当需要解析JSON值或其他动态的事情。
* 这时就可以使用Map对象为代理属性提供代理
*/
var user = UserPropertyByDelegate(mapOf(
"name" to
"john",
"age" to
15
))
println(
"${user.name} age is ${user.age}")
}