網(wǎng)站首頁 編程語言 正文
1.Kotlin委托
在委托模式中,兩個(gè)對(duì)象參與處理同一請(qǐng)求,接受請(qǐng)求的對(duì)象講請(qǐng)求委托給另外一個(gè)對(duì)象來處理。Kotlin直接支持委托模式,更加優(yōu)雅,簡(jiǎn)潔。kotlin通過關(guān)鍵字by
實(shí)現(xiàn)委托。
2.類委托
類的委托即一個(gè)類中定義的方法實(shí)際是調(diào)用另一個(gè)類的對(duì)象的方法來實(shí)現(xiàn)的。
以下實(shí)例中派生類Derived繼承了接口Base所有方法,并且委托一個(gè)傳入的Base類的對(duì)象來執(zhí)行這些方法。
//創(chuàng)建接口 interface Base { fun print() } //實(shí)現(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的對(duì)象實(shí)例內(nèi)部,而且編譯器將會(huì)生成繼承自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.屬性委托
屬性委托指的是一個(gè)類的某個(gè)屬性值不是在類中直接進(jìn)行定義,而是將其委托給一個(gè)代理類,從而實(shí)現(xiàn)對(duì)該類的屬性統(tǒng)一管理。
屬性委托語法格式:
val/var <屬性名>:<類型> by <表達(dá)式>
by關(guān)鍵字之后的表達(dá)式就是委托,屬性的get()方法(以及set()方法)將被委托給這個(gè)對(duì)象的getValue()和setValue()方法。屬性委托不必實(shí)現(xiàn)任何接口,但是必須提供getValue()函數(shù)(對(duì)于var屬性,還需要setValue()函數(shù))。
3.1定義一個(gè)被委托的類
該類包含getValue()方法和setValue()方法,且參數(shù)thisRef為進(jìn)行委托的類的對(duì)象,prop為進(jìn)行委托的屬性的對(duì)象。
//定義包含屬性委托的類 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)置了很多工廠方法來實(shí)現(xiàn)屬性的委托。
延遲屬性Lazy
lazy()是一個(gè)函數(shù),接受一個(gè)Lambda表達(dá)式作為參數(shù),返回一個(gè)Lazy<T>實(shí)例的函數(shù),返回的實(shí)例可以作為延遲屬性的委托:第一次調(diào)用get()會(huì)執(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把屬性存儲(chǔ)在映射中
一個(gè)常見的用例是在一個(gè)映射(map)里存儲(chǔ)屬性的值。這經(jīng)常出現(xiàn)在像解析JSON或者其他"動(dòng)態(tài)"事情的應(yīng)用中。這種情況下,你可以使用映射實(shí)例自身作為委托來實(shí)現(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適用于那些無法在初始化階段就確定屬性值的場(chǎng)合。
class Foo{ var notNullBar:String by Delegates.notNull<String>() } foo.notNullBar="bar" println(foo.notNullBar)
需要注意,如果屬性在賦值前就被訪問的話則會(huì)拋出異常。
原文鏈接:https://blog.csdn.net/Goals1989/article/details/127179137
相關(guān)推薦
- 2022-02-25 C++實(shí)現(xiàn)單例模式的方法_C 語言
- 2022-09-14 Python定制類你不知道的魔術(shù)方法_python
- 2024-04-08 Spring在多線程環(huán)境下如何確保事務(wù)一致性
- 2023-01-12 Golang遠(yuǎn)程調(diào)用框架RPC的具體使用_Golang
- 2022-07-10 深拷貝的三種實(shí)現(xiàn)方式
- 2022-09-24 Go?類型轉(zhuǎn)化工具庫cast函數(shù)詳解_Golang
- 2022-11-09 LyScript實(shí)現(xiàn)Hook隱藏調(diào)試器的方法詳解_python
- 2022-11-14 JVM中的垃圾回收
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支