Kotlin 分享 之委托与委托属性

参考:

http://www.runoob.com/kotlin/kotlin-delegated.html

本节,分享内容如下:

  1. 委托的定义;
  2. 类委托;
  3. 委托属性;
  4. 局部委托属性;
  5. 委托属性的要求;
  6. 提供委托;

什么是委托

  • Java中的代理(Proxy)
    在代理模式中,自己不干活,将或全部抛给另一方;
  • 在委托或代理中,有2个对象参与处理同一个请求;
  • kotlin直接支持委托通过关键字by实现委托

类委托

一个类中定义的方法实际上调用另一个类的对象的方法来实现的;

实现步骤:

  • 演示代码;
  • 反编译代码;
  • 委托类也可添加自己的方法;

委托属性

属性委托指的是一个类的某个属性值不是在类中直接进行定义,
而是将其托付给一个代理类,从而实现对该类的属性统一管理

语法格式:

val/var <属性名>: <类型> by <表达式>

by 关键字之后的表达式就是委托,属性的get、set将委托给该对象的
getValue()setValue()
属性委托不必实现任何接口, 但必须提供 getValue() 函数(对于 var属性,还需要 setValue() 函数)。

实现属性委托的例子

  1. 首先,我们定义一个被委托的类,如下:

    class Baby {
    var name:String by Delegate()
    }

  2. 定义属性委托类 (setValue 与 getValue 格式固定):

    class Delegate { operator fun getValue(thisRef : Any?, property: KProperty<*> ):String { return ("$thisRef delegating $property.name") } operator fun setValue(thisRef: Any?, property: KProperty<*>, value:String) { println("$value has been assigned to ${property.name} in ${thisRef}") } }

委托属性的常见的3种

    1. 延迟属性(lazy):首次访问时计算;
    1. 可观察属性(observable);
    1. 多个属性存在一个map中,而非单独字段;

针对这些,kotlin提供有用的工厂方法;

1. 延迟属性(lazy)

接收一个lambda并返回一个Lazy<T>实例的函数,该实例作为延迟属性的委托;

class LazyClass {

    // 延迟属性委托(val)
    val lazyValue: String by lazy {
        println("get value")
        "Hello"
    }

    // 延迟加载 (var)
    lateinit var lateValue: String

    fun printLateValue(): String {
        lateValue = "abc"
        return lateValue
    }
}

复习一下延迟加载,为什么是valvar

2. 可观察属性(Observable)

也就是让属性实现观察者模式;

Delegates.observable() 函数接受两个参数;我们来写代码

```
// 可观察的属性
class Test4_Property_Observable {
    var name: String by Delegates.observable("zhaoyu") { prop, old, new ->
        println("${prop.name} $old ==>$new")
    }
}
```

我们升级一下程序,使用 vetoable

```
class Test5_Property_Observable_2 {
    var name: String by Delegates.vetoable("zhaoyu") { prop, old, new ->
        if (new == "ergouzi") {
            println("fuck!!! the name is not appropriate")
            return@vetoable false   // 局部返回,我们后面会说的,先别着急
        }
        return@vetoable true
    }
}
```

3. 多个属性存在一个map中(Observable)

常见的用例是在一个映射(map)里存储属性的值;
经常出现在像解析 JSON 或者做其他"动态"事情的应用中。 可以使用映射实例自身作为委托来实现委托属性。
json的演示就不做了。相信大家会的;

```
data class Test6_Property_map(val map:Map<String, Any?>) {
    val name:String by map
    val pwd:String by map
}

fun main(args: Array<String>) {
    val map = mapOf("name" to "better", "pwd" to "123")
    val test = Test6_Property_map(map)
    println("${test.name} ===> ${test.pwd}")
}
```

局部委托属性

可以将局部变量声明为委托属性。 可以使一个局部变量惰性初始化:
没有合适例子;

委托属性的要求

  1. 对于只读(val)属性,委托必须提供一个名为getValue函数,其参数如下:
  • thisRef - 须与属性所有者类型类型相同或其超类型;
  • property - 必须是类型 KProperty<*>或其super;
  1. 对于可变(var)属性,需提供一个额外的setValue函数,具体看上面例子吧;

提供委托

通过定义provideDelegate操作符,可扩展创建属性实现所委托对象的逻辑;如by右侧所使用的对象将provideDelegate定义为成员或扩展函数,那么会调用该函数来创建属性委托实例;

跳过;
看不明白;

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容

  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,146评论 9 118
  • Kotlin 属性 要讲 Kotlin 的委托属性,要先从 Kotlin 的属性说起,当然关于属性的定义就不多介绍...
    哦好么人阅读 11,481评论 3 11
  • 简述 在java中一些属性的具有相同的行为怎么办,抽象出类然后再去依赖调用,而在Kotlin中只需要一个by关键字...
    i校长阅读 2,614评论 0 4
  • 1.意想不到:生命如此美好,王老师给果果做艾灸时,无意加入了他俩的聊天,果果的心里竟然还有另外一个世界,她和上帝通...
    国粹堂1阅读 239评论 0 0
  • 今天,网上一段题为《6岁小姑娘被妈妈打,大声训斥妈妈讲道理,条条听着都是那么揪心》的视频吸引了我,起初以为是一个萌...
    凤儿有约阅读 609评论 0 3