类委托
interface Base{
fun print()
}
class BaseImpl(val x:Int):Base{
override fun print() {
print(x)
}
}
class Derived(b:Base):Base by b
fun main(args: Array<String>) {
val b=BaseImpl(10)
Derived(b).print()
}
Derived继承 Base 接口,指定 b对象代理实现全部的公共方法,b存储在 Derived实例对象内部。
属性委托
import kotlin.reflect.KProperty
// 定义包含属性委托的类
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)
}
//输出结果
Example@31cefde0, 这里委托了 p 属性
Example@31cefde0 的 p 属性赋值为 Runoob
Example@31cefde0, 这里委托了 p 属性
延迟属性 Lazy
val lazyValue:String by lazy {
println("lazy")
"hello"
}
fun main(args: Array<String>) {
println(lazyValue)
println(lazyValue)
}
//输出结果
lazy
hello
hello
lateinit 和 by lazy区别:
1.lazy{} 只能用val类型, lateinit 只能用var类型
2.lateinit不能用在可空的属性上和基本类型上
可观察属性 Observable
Delegates.observable() 函数接受两个参数: 第一个是初始化值, 第二个是属性值变化事件的响应器(handler)。在属性赋值后会执行事件的响应器(handler),它有三个参数:被赋值的属性、旧值和新值:
import kotlin.properties.Delegates
class User{
var name:String by Delegates.observable("初始值"){
prop,old,new->
println("旧值:$old->新值:$new")
}
}
fun main(args: Array<String>) {
val user=User()
user.name="第一次赋值"
user.name="第二次赋值"
}
//输出结果
旧值:初始值->新值:第一次赋值
旧值:第一次赋值->新值:第二次赋值
把属性储存在映射中
class Site(val map: Map<String, Any?>) {
val name: String by map
val url: String by map
}
fun main(args: Array<String>) {
// 构造函数接受一个映射参数
val site = Site(mapOf(
"name" to "菜鸟教程",
"url" to "www.runoob.com"
))
// 读取映射值
println(site.name)
println(site.url)
}
//打印结果
菜鸟教程
www.runoob.com
如果使用 var 属性,需要把 Map 换成 MutableMap:
class Site(val map: MutableMap<String, Any?>) {
val name: String by map
val url: String by map
}
fun main(args: Array<String>) {
var map:MutableMap<String, Any?> = mutableMapOf(
"name" to "菜鸟教程",
"url" to "www.runoob.com"
)
val site = Site(map)
println(site.name)
println(site.url)
println("--------------")
map.put("name", "Google")
map.put("url", "www.google.com")
println(site.name)
println(site.url)
}
//打印结果
菜鸟教程
www.runoob.com
--------------
Google
www.google.com
Not Null
notNull 适用于那些无法在初始化阶段就确定属性值的场合。
注意:如果属性在赋值前就被访问的话则会抛出异常。
class Foo {
var notNullBar: String by Delegates.notNull<String>()
}
foo.notNullBar = "bar"
println(foo.notNullBar)