Kotlin學(xué)歷之委托屬性

簡述

在java中一些屬性的具有相同的行為怎么辦屉来,抽象出類然后再去依賴調(diào)用右遭,而在Kotlin中只需要一個by關(guān)鍵字就能省去繁瑣的依賴勾笆。屬性的委托主要是統(tǒng)一實現(xiàn)了對屬性的set芳肌,get困食。Kotlin 標(biāo)準(zhǔn)庫還為幾種有用的委托提供了工廠方法:

延遲屬性(lazy properties): 其值只在首次訪問時計算,

可觀察屬性(observable properties): 監(jiān)聽器會收到有關(guān)此屬性變更的通知邢疙,

把多個屬性儲存在一個映射(map)中棍弄,而不是每個存在單獨(dú)的字段中。

下面將通過編譯器的代碼例子詳細(xì)學(xué)習(xí)疟游。

例1:聲明方式

val/var <屬性名>: <類型> by <表達(dá)式>

例2:by <表達(dá)式> 這個表達(dá)式怎么寫,下面一個例子

class ByDemo{
? ? ? ? ?operator fun getValue(thisRef: Any?,property: KProperty<*>) : <類型>{
? ? ? ? ? ? ? ? ? return <類型>
? ? ? ? ?}
? ? ? ? ?operator fun setValue(thisRef: Any?,property: KProperty<*>,value:<類型>){
? ? ? ? ? ? ? ? ? ?print()
? ? ? ? ?}
}

解釋下這個例子:
定義一個ByDemo類痕支,然后再定義兩個方法getValue(),setValue() , 方法需要operator關(guān)鍵字修飾颁虐,thisRef: Any? :thisRef是當(dāng)前屬性的對象,property: KProperty<*>:property是當(dāng)前屬性卧须,property.name 屬性名稱另绩,value:<類型> 這個就是當(dāng)前屬性的值和類型。
在定義委托表達(dá)式需要注意的點:

對于只讀屬性(也就是說val屬性), 它的委托必須提供一個名為getValue()的函數(shù)花嘶。
thisRef: Any? 必須是該屬性當(dāng)前類或者基類(Any是任何類的基類)笋籽。
property: KProperty<*>這個參數(shù)的類型必須是 KProperty<*> , 或者是它的基類。
getValue()返回值類型必須與屬性類型相同(或者是它的子類型)椭员。
value:<類型>這個參數(shù)的類型必須與屬性類型相同, 或者是它的基類
方法名不能改必須是getValue车海、setValue,并且必須用operator關(guān)鍵字修飾

接下來看下Kotlin 標(biāo)準(zhǔn)庫提供的委托

例1:lazy()是接受一個 lambda 并返回一個Lazy 實例的函數(shù)隘击,返回的實例可以作為實現(xiàn)延遲屬性的委托: 第一次調(diào)用get()會執(zhí)行已傳遞給lazy()的 lamda 表達(dá)式并記錄結(jié)果侍芝, 后續(xù)調(diào)用get()只是返回記錄的結(jié)果。

lazy測試

var類型屬性不能設(shè)置為延遲加載屬性埋同,因為在lazy中并沒有setValue(…)方法

lazy是線程安全的州叠。如果在不考慮多線程問題或者想提高更多的性能,也可以使

用 lazy(LazyThreadSafeMode.NONE){ … }

例2:Observable 使用是通過類Delegates.observable()調(diào)用的凶赁,需要兩個參數(shù):第一個是初始化值, 第二個是屬性值變化事件的響應(yīng)器(handler)

var name: String by Delegates.observable("demo",{

? ? ? kProperty , oldName , newName->

? ? ? ?println("kProperty:${kProperty.name}| oldName:$oldName| newName:$newName")

})

"demo" 為第一個參數(shù)咧栗,用意是給name賦值逆甜。

"demo"后面大括號內(nèi)容為第二個參數(shù),表達(dá)式有三個值:每次給name賦值都會回調(diào)它致板,就跟觀察者一樣忆绰,kProperty是當(dāng)前屬性,oldName是它的舊值可岂,newName是它的新值错敢。這里都是變量名可以隨意起名字,你也可以這樣 { a, b, c -> println( a+b+c) } 當(dāng)然這樣命名不規(guī)范不推薦缕粹,這就是為了說明可以改稚茅。

例3:Vetoable 使用也是通過 類Delegates.vetoable()調(diào)用,同樣也是兩個參數(shù)平斩,第一個是初始化值, 第二個是屬性值變化事件的響應(yīng)器(handler)亚享,是可觀察屬性(Observable)的一個特例,不同的是給屬性賦值的時候會加以判斷绘面,是否要將新值賦于該變量欺税。

var name: String by Delegates.vetoable("demo",{

? ? ? ? kProperty , oldName , newName->

? ? ? ? println("kProperty:${kProperty.name}| oldName:$oldName| newName:$newName")

? ? ? ? newName.contains("demo") //判斷新的值是否包含demo字符,有才會賦值

})

例4:notNull 使用 通過類 Delegates.notNull() 調(diào)用揭璃,在java中我們會遇到很多的null判斷晚凿,空的話會拋出異常,Kotlin為了簡化該操作瘦馍,追求高效率的工作歼秽,幫我們實現(xiàn)了該方法,下面看下源碼就明白了情组,在value等于null的時候拋出IllegalStateException異常燥筷,說該值必須初始化。

notNull源碼

例5:map映射院崇,Kotlin給咱們提供了 map到 對象屬性的映射肆氓,主要用于json解析中,這種委托的寫法和上面的不太一樣底瓣,首先看下代碼

class User(val map: Map) {
? ? ? ?val name: String by map
? ? ? ?val age: Int by map
}

User類接受一個Map集合谢揪,會自動將 Map中key 為name的值賦給name, age為key的值賦給age濒持。這樣用起來確實挺簡單方便键耕。

總結(jié)

委托屬性在實際開發(fā)中還是會應(yīng)用很多的,這屬于kotlin中的重點之一吧柑营,需要好好研究下屈雄,到此為止,Kotlin中的類與對象就告一段落官套,不知道你們學(xué)的怎么樣酒奶,下期繼續(xù)學(xué)習(xí)kotlin中的又一個特點:空安全蚁孔。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市惋嚎,隨后出現(xiàn)的幾起案子杠氢,更是在濱河造成了極大的恐慌,老刑警劉巖另伍,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鼻百,死亡現(xiàn)場離奇詭異,居然都是意外死亡摆尝,警方通過查閱死者的電腦和手機(jī)温艇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來堕汞,“玉大人勺爱,你說我怎么就攤上這事⊙都欤” “怎么了琐鲁?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長人灼。 經(jīng)常有香客問我围段,道長,這世上最難降的妖魔是什么挡毅? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任蒜撮,我火速辦了婚禮,結(jié)果婚禮上跪呈,老公的妹妹穿的比我還像新娘。我一直安慰自己取逾,他們只是感情好耗绿,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著砾隅,像睡著了一般误阻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上晴埂,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天究反,我揣著相機(jī)與錄音,去河邊找鬼儒洛。 笑死精耐,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的琅锻。 我是一名探鬼主播卦停,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼向胡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了惊完?” 一聲冷哼從身側(cè)響起僵芹,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎小槐,沒想到半個月后拇派,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡凿跳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年件豌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拄显。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡苟径,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出躬审,到底是詐尸還是另有隱情棘街,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布承边,位于F島的核電站遭殉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏博助。R本人自食惡果不足惜险污,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望富岳。 院中可真熱鬧蛔糯,春花似錦、人聲如沸窖式。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽萝喘。三九已至淮逻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間阁簸,已是汗流浹背爬早。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留启妹,地道東北人筛严。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像翅溺,于是被迫代替她去往敵國和親脑漫。 傳聞我的和親對象是個殘疾皇子髓抑,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容