Kotlin Koans 学习笔记 —— Unit 4

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011133887/article/details/86491142

Kotlin Koans 学习笔记 —— Unit 1
Kotlin Koans 学习笔记 —— Unit 2
Kotlin Koans 学习笔记 —— Unit 3

32 属性

将自定义setter添加到’PropertyExample.propertyWithCounter’,以便每次’propertyWithCounter’被赋值时,'counter’属性都会递增。

class PropertyExample() {
    var counter = 0

    var propertyWithCounter: Int=0
        set(value) {
            counter++
            field = value //field是幕后字段
        }
}

关于本段请仔细阅读:属性与字段
如果不清楚属性与字段的不同可以阅读:Kotlin类和对象 (三)— 属性和字段

33 懒加载

添加自定义getter以使’lazy’属性懒加载。
在第一次访问时,它应该通过调用’initializer()来初始化。
您可以根据需要添加任意数量的其他属性。不要使用委托属性!

class LazyProperty(val initializer: () -> Int) {
    var value: Int? = null
    val lazy: Int
        get() {
            if (value == null) { //类似于Java中实现单例模式时的玩法
                value = initializer()
            }
            return value!!
        }
}

34 委托

如果使用委托的话,我们可以这样写:

class LazyPropertyUsingDelegates(val initializer: () -> Int) {
    val lazyValue: Int by lazy(initializer)
    //by关键字用于实现属性委托,lazy关键字是接受一个lambda表达式,
    // 在第一次加载字段的时候执行,并将结果赋予该字段,之后初始器不会再被调用。
}

如果你还没接触过 lazy 推荐阅读:Kotlin 变量, 使用 Lazy 还是 Late

35 委托是如何工作的

委托表达式必须具有特殊的“get”和“set”方法。
您可以在下面看到他们的签名作为“ReadWriteProperty”接口的成员。
实现类’EffectiveDate’的成员,以便委派给它。
仅在’timeInMillis’属性中存储以毫秒为单位的时间。
使用扩展函数’MyDate.toMillis’和’Long.toDate’。

关于属性委托可以看这篇文章:Kotlin中理解委托属性,并自定义委托

class EffectiveDate<R> : ReadWriteProperty<R, MyDate> {
    var timeInMillis: Long? = null

    operator override fun getValue(thisRef: R, property: KProperty<*>): MyDate = timeInMillis!!.toDate()
    operator override fun setValue(thisRef: R, property: KProperty<*>, value: MyDate) {
        timeInMillis = value.toMillis()
    }
}

我们来看一下测试代码:

@Test fun testDate() {
    val d = D()
    /* Month numbering starts with 0 (0-Jan, 1-Feb, ... 11-Dec) */
    d.date = MyDate(2014, 1, 13)
    assertEquals(2014, d.date.year)
    assertEquals(1, d.date.month)
    assertEquals(13, d.date.dayOfMonth)
}

可以看到在题目中 D 类的属性 date 通过关键字 by 委托给了 EffectiveDate 这个类,该类实现了 ReadWriteProperty 接口。在EffectiveDate 中当date 被赋值时,将会调用 setValue() 函数,我们将MyDate 装换成 Long 来保存,在使用 date 属性的成员属性时,会调用 getValue() 方法,返回的是 MyDate 类型。

猜你喜欢

转载自blog.csdn.net/u011133887/article/details/86491142