Step into Kotlin - 24 - delegate
来源:互联网 发布:英语发音自测软件 编辑:程序博客网 时间:2024/05/16 10:41
目录
- Delegate
- 类的委托
- 属性的委托
- 内置属性委托
- 分类
- Lazy Properties
- Observable Properties
- Not Null
- Map Val
- Delegate
摘要
类的委托,属性的委托,Lazy Properties,Observable Properties,Not Null,Map Val
Delegate
类的委托
类的委托使用 by 语句
。
创建接口和子类
interface Base { fun println()}class BaseImpl(val x: Int) : Base { override fun println() { println(x) }}
建立委托类
class Derived(b: Base) : Base by b
以上 Derived 类
创建了所有来自 Base 的方法
,并且委托一个传入的 Base 的对象
执行这些方法。
使用委托类
val b = BaseImpl(19)b.println() // 19Derived(b).println() // 19
属性的委托
创建被委托类
class Delegate { fun get(thisRef: Any?, prop: PropertyMetadata): String { return "$thisRef, thank you for delegating '${prop.name}}' to me!" } fun set(thisRef: Any?, prop: PropertyMetadata, value: String) { println("$value has been assigned to '${prop.name} in $thisRef.'") }}
创建委托类
class Example { var p: String by Delegate()}
使用委托
val e = Example()println(e.p)e.p = "NEW"
内置属性委托
分类
Kotlin API 中有两种标准的属性委托方法,一种是 lazy properties,一种是 observable properties。
Lazy Properties
- Lazy Properties 在第一次被访问时才会获取值。
- Lazy Properties 是通过 lazy 方法来实现的。
- lazy 方法接收一个Lambda 表达式,在第一次执行时会计算 Lambda 的值然后存储起来,之后访问的话会直接取得保存的值,而不会重新计算。
val lazy: String by lazy { println("computed!") "Hello ${System.currentTimeMillis()}"}println("lazy is ${lazy}")println("lazy is ${lazy}")
lazy 是非线程安全的,线程安全的版本见下面的例子
val blockLazy: String by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { println("computed2!") "Hello2 ${System.currentTimeMillis()}"}
Observable Properties
- Observable Properties 被存储在一个 Map 中,而不是单独的属性。
- Observable Properties 可以设置监听值改变事件的监听器。
- Observable Properties 是通过 observable()方法实现的。
- observable()方法接收两个参数,第一个为初始值,第二个为监听的回调Handler,该 Handler 接收三个参数:被设置的属性,旧值,新值。
class User { var name: String by Delegates.observable("<no name>") { d, old, new -> println("$old -> $new") }}val user = User()user.name = "first"user.name = "second"
也可以使用 vetoable()
代替 observable()
,该方法功能类似,但是返回布尔值,用以表示这次设置是否有效。
class User { var age: Int by Delegates.vetoable(0) { d, old, new -> println("$old -> $new") if (new < 20) true else false }}val user = User()user.age = 10println(user.age)user.age = 20println(user.age)
Not Null
由于 Kotlin 不允许定义任何非空的非抽象属性,但是实际使用时可能也需要定义这样的属性,这时就需要 not null 方法来实现。
class NotNullFoo { var bar: String by Delegates.notNull()}val foo = NotNullFoo()foo.bar = "bar"
Map Val
Map Val 可以用于将所有属性保存在一个 Map 中,在使用 JSON 等数据格式或者实现某些动态特性时这种功能很有用。
class Account(val map: Map<String, Any?>) { val name: String by Delegates.mapVal(map) { o, p -> println("$o -> $p") "default name" } val age: Int by Delegates.mapVal(map) { o, p -> println("$o -> $p") 0 }}val account = Account(mapOf( "name" to "John", "age" to 25))println(account.name)println(account.age)
mapVar()为以上的可变版本。
0 0
- Step into Kotlin - 24 - delegate
- Step into Kotlin
- Step into Kotlin - 01 - 入门
- Step into Kotlin - 02 - 数据类型
- Step into Kotlin - 04 - 函数
- Step into Kotlin - 06 - 异常
- Step into Kotlin - 08 - 数组
- Step into Kotlin - 09 - 集合
- Step into Kotlin - 11 - 类
- Step into Kotlin - 13 - 包
- Step into Kotlin - 14 - 继承
- Step into Kotlin - 15 - 注解
- Step into Kotlin - 17 - 泛型
- Step into Kotlin - 22 - Xml
- Step into Kotlin - 05 - 流程控制
- Step into Kotlin - 12 - Object 与枚举
- Step into Kotlin - 18 - Extension 与 this
- Step into Kotlin - 19 - 正则表达式
- 初识树莓派
- 数据库相关(4) 事务处理
- eclipse 连接不到genymotion
- Activity的加载模式
- depends.exe 使用说明
- Step into Kotlin - 24 - delegate
- C# 委托的同步调用和异步调用
- 写给新手程序员的一封信(转)
- oracle数据类型和对应的java类型
- Label center
- uva10870(矩阵快速幂)
- SQL Server 中 RAISERROR 的用法
- 杭电 HDU ACM 1548 A strange lift(简单广搜)
- HDU 3006 The Number of set (状态压缩dp)