Kotlin by關(guān)鍵字作用及使用介紹
1.Kotlin委托
在委托模式中,兩個對象參與處理同一請求,接受請求的對象講請求委托給另外一個對象來處理。Kotlin直接支持委托模式,更加優(yōu)雅,簡潔。kotlin通過關(guān)鍵字by
實現(xiàn)委托。
2.類委托
類的委托即一個類中定義的方法實際是調(diào)用另一個類的對象的方法來實現(xiàn)的。
以下實例中派生類Derived繼承了接口Base所有方法,并且委托一個傳入的Base類的對象來執(zhí)行這些方法。
//創(chuàng)建接口 interface Base { fun print() } //實現(xiàn)此接口的被委托的類 class BaseImp(val x:Int) : Base { override fun print() { println(x) } } //通過關(guān)鍵字by建立委托類 class Derived (b:Base):Base by b class Main { companion object{ @JvmStatic fun main(args: Array<String>) { var baseImp=BaseImp(100) Derived(baseImp).print() //輸出100 } } }
在Derived聲明中,by子句表示,將b保存在Derived的對象實例內(nèi)部,而且編譯器將會生成繼承自Base接口的所有方法,并將調(diào)用轉(zhuǎn)發(fā)給b。我們看看生成的java代碼。
public final class Derived implements Base { // $FF: synthetic field private final Base $$delegate_0; public Derived(@NotNull Base b) { Intrinsics.checkNotNullParameter(b, "b"); super(); this.$$delegate_0 = b; } public void print() { this.$$delegate_0.print(); } }
3.屬性委托
屬性委托指的是一個類的某個屬性值不是在類中直接進(jìn)行定義,而是將其委托給一個代理類,從而實現(xiàn)對該類的屬性統(tǒng)一管理。
屬性委托語法格式:
val/var <屬性名>:<類型> by <表達(dá)式>
by關(guān)鍵字之后的表達(dá)式就是委托,屬性的get()方法(以及set()方法)將被委托給這個對象的getValue()和setValue()方法。屬性委托不必實現(xiàn)任何接口,但是必須提供getValue()函數(shù)(對于var屬性,還需要setValue()函數(shù))。
3.1定義一個被委托的類
該類包含getValue()方法和setValue()方法,且參數(shù)thisRef為進(jìn)行委托的類的對象,prop為進(jìn)行委托的屬性的對象。
//定義包含屬性委托的類 class Example { var p:String by Delegate() } //委托的類 open 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") } } class Main { companion object{ @JvmStatic fun main(args: Array<String>) { var e=Example() println(e.p) //訪問該屬性 調(diào)用getValue函數(shù) e.p="rururn" //調(diào)用setValue()函數(shù) println(e.p) } } }
輸出結(jié)構(gòu)為:
com.geespace.lib.kotlin.by2.Example@3f99bd52,這里委托了p 屬性
com.geespace.lib.kotlin.by2.Example@3f99bd52 的 p 屬性賦值為 rururn
com.geespace.lib.kotlin.by2.Example@3f99bd52,這里委托了p 屬性
3.2標(biāo)準(zhǔn)委托
Kotlin的標(biāo)準(zhǔn)庫已經(jīng)內(nèi)置了很多工廠方法來實現(xiàn)屬性的委托。
延遲屬性Lazy
lazy()是一個函數(shù),接受一個Lambda表達(dá)式作為參數(shù),返回一個Lazy<T>實例的函數(shù),返回的實例可以作為延遲屬性的委托:第一次調(diào)用get()會執(zhí)行已傳遞給lazy()的lamda表達(dá)式并記錄結(jié)果,后續(xù)調(diào)用get()只是返回記錄的結(jié)果。
class LazyTest { companion object{ val lazyValue:String by lazy { println("computed!") //第一次調(diào)用輸出,第二次調(diào)用不執(zhí)行 "Hello" } @JvmStatic fun main(args: Array<String>) { println(lazyValue) println(lazyValue) } } }
執(zhí)行輸出結(jié)果:
computed!
Hello
Hello
3.3把屬性存儲在映射中
一個常見的用例是在一個映射(map)里存儲屬性的值。這經(jīng)常出現(xiàn)在像解析JSON或者其他"動態(tài)"事情的應(yīng)用中。這種情況下,你可以使用映射實例自身作為委托來實現(xiàn)委托屬性。
class Site(val map:Map<String,Any?>) { val name:String by map val url:String by map } class TestMain { companion object{ @JvmStatic fun main(args: Array<String>) { val site=Site(mapOf( "name" to "maozh", "url" to "www.baidu.com" )) //讀取映射值 println(site.name) println(site.url) } } }
執(zhí)行輸出結(jié)果:
maozh
www.baidu.com
3.4Not Null
notNull適用于那些無法在初始化階段就確定屬性值的場合。
class Foo{ var notNullBar:String by Delegates.notNull<String>() } foo.notNullBar="bar" println(foo.notNullBar)
需要注意,如果屬性在賦值前就被訪問的話則會拋出異常。
到此這篇關(guān)于Kotlin by關(guān)鍵字作用及使用介紹的文章就介紹到這了,更多相關(guān)Kotlin by關(guān)鍵字內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
android 仿微信demo——微信消息界面實現(xiàn)(移動端)
本系列文章主要介紹了微信小程序-閱讀小程序?qū)嵗╠emo),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧,希望能給你們提供幫助2021-06-06Android?Bugreport實現(xiàn)原理深入分析
這篇文章主要介紹了Android?Bugreport實現(xiàn)原理,Bugreport主要用于分析手機(jī)的狀態(tài),在應(yīng)用開發(fā)中,程序的調(diào)試分析是日常生產(chǎn)中進(jìn)程會進(jìn)行的工作,Bugreport就是很常用的工具,需要的朋友可以參考下2024-05-05Android學(xué)習(xí)筆記-保存文件(Saving Files)
這篇文章主要介紹了Android中保存文件(Saving Files)的方法,需要的朋友可以參考下2014-10-10