付費(fèi)下載
下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
【移動(dòng)應(yīng)用開發(fā)技術(shù)】如何在Kotlin中使用擴(kuò)展函數(shù)和擴(kuò)展屬性
如何在Kotlin中使用擴(kuò)展函數(shù)和擴(kuò)展屬性?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面在下將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。Kotlin能夠擴(kuò)展一個(gè)類的新功能而無需繼承該類或者使用像裝飾者這樣的設(shè)計(jì)模式。這通過叫做擴(kuò)展的特殊聲明完成。例如,你可以為一個(gè)你不能修改的、來自第三方庫(kù)中的類編寫一個(gè)新的函數(shù)。這個(gè)新增的函數(shù)就像那個(gè)原始類本來就有的函數(shù)一樣,可以用普通的方法調(diào)用。這種機(jī)制稱為擴(kuò)展函數(shù)。public
class
Utils
{
public
static
float
dp2px(int
dpValue)
{
return
(0.5f
+
dpValue
*
Resources.getSystem().getDisplayMetrics().density);
}
}在代碼中直接調(diào)用Utils.dp2px(100)來使用,val
dp2px
=
Utils.dp2px(100)如果用kotlin擴(kuò)展函數(shù)的方式來實(shí)現(xiàn),會(huì)是怎么調(diào)用呢?val
dp2px
=
100.dp2px()是不是很驚訝,100作為一個(gè)Int,竟然直接調(diào)用了一個(gè)dp2px方法,如果你去源碼里找找,其實(shí)是沒有個(gè)方法的。我們沒有動(dòng)源碼,而是使用拓展函數(shù)的方式為Int增加了一個(gè)方法。fun
Int.dp2px():
Float
{
return
(0.5f
+
this
*
Resources.getSystem().displayMetrics.density)
}擴(kuò)展函數(shù)我們?cè)賮砼e個(gè)?,有一個(gè)Person類如下class
Person(val
name:
String)
{
fun
eat()
{
Log.i(name,
"I'm
going
to
eat")
}
fun
sleep()
{
Log.i(name,
"I'm
going
to
sleep")
}
}它有兩個(gè)方法,一個(gè)是eat、一個(gè)是sleep,調(diào)用的話就分別打印相應(yīng)的Log。我們現(xiàn)在不想動(dòng)Person類,但是又想給他增加一個(gè)新的方法,怎么做呢。我們可以新建一個(gè)文件PersonExtensions.kt,再通過一下代碼實(shí)現(xiàn),就可以為Person類新增一個(gè)drink方法啦。fun
Person.drink()
{
Log.i("Person",
"${}:
I'm
going
to
drink")
}聲明一個(gè)擴(kuò)展函數(shù),我們需要用一個(gè)接收者類型也就是被擴(kuò)展的類型來作為他的前綴。上面我們就是以Person作為一個(gè)擴(kuò)展函數(shù)的接收類型,為其拓展來drink方法。我們?cè)谄浞椒ㄖ姓{(diào)用了this,這個(gè)this指的就是調(diào)用這個(gè)拓展方法的當(dāng)前Person對(duì)象。擴(kuò)展函數(shù)調(diào)用的話也和普通的方法相同。但是你會(huì)發(fā)現(xiàn)IDE顯示的方法顏色有點(diǎn)不一樣。由此也可以看出普通的方法和我們的拓展函數(shù)是不同的。下面我們來看看擴(kuò)展函數(shù)的實(shí)際實(shí)現(xiàn)。在AndroidStudio中,我們可以查看kotlin文件的字節(jié)碼,然后再Decompile為Java代碼。上面我們?yōu)镻erson擴(kuò)展函數(shù)轉(zhuǎn)為Java代碼后如下。@Metadata(
mv
=
{1,
1,
15},
bv
=
{1,
0,
3},
k
=
2,
d1
=
{"\u0000\f\n\u0000\n\u0002\u0010\u0002\n\u0002\u0018\u0002\n\u0000\u001a\n\u0010\u0000\u001a\u00020\u0001*\u00020\u0002¨\u0006\u0003"},
d2
=
{"cook",
"",
"Lcom/chaochaowu/kotlinextension/Person;",
"app_debug"}
)
public
final
class
PersonExtensionsKt
{
public
static
final
void
cook(@NotNull
Person
$this$cook)
{
Intrinsics.checkParameterIsNotNull($this$cook,
"$this$cook");
Log.i("Person",
$this$cook.getName()
+
":
I'm
going
to
cook");
}
}妹想到啊,它原來是一個(gè)staticfinal聲明的靜態(tài)方法,它的入?yún)⑹且粋€(gè)Person類型,也就是我們之前的接收類型。那在Java代碼中能不呢調(diào)用呢?PersonExtensionsKt.cook(new
Person("Bob"));竟然也沒有報(bào)錯(cuò)!由此可見,所謂擴(kuò)展函數(shù)并不是真正的在類中增加了一個(gè)方法,而是通過外部文件的靜態(tài)方法來實(shí)現(xiàn),其實(shí)就是和Utils類一個(gè)道理。因?yàn)閷⒁粋€(gè)Person作為入?yún)魅肓朔椒ㄖ?,所以我們也就可以在方法?nèi)對(duì)這個(gè)Person對(duì)象進(jìn)行操作,這也就是在擴(kuò)展方法中我們可以使用this來訪問Person屬性的原因。再來看一個(gè)特殊的例子。val
s:
String?
=
null
s.isNullOrEmpty()上面的代碼中,s的值為null,我們用null去調(diào)用了一個(gè)方法,這會(huì)不會(huì)報(bào)錯(cuò)呢?按照以前的經(jīng)驗(yàn),一個(gè)null去調(diào)用一個(gè)方法,必然會(huì)報(bào)空指針的異常,但是上面的代碼卻是不會(huì)崩的。為什么哩?其實(shí)isNullOrEmpty是CharSequence?的一個(gè)擴(kuò)展方法,我們可以看一下它的源碼。@ernal.InlineOnly
public
inline
fun
CharSequence?.isNullOrEmpty():
Boolean
{
contract
{
returns(false)
implies
(this@isNullOrEmpty
!=
null)
}
return
this
==
null
||
this.length
==
0
}contract這個(gè)契約方法這邊我們不需要注意,不影響。主要是看returnthis==null||this.length==0這句話。它先是判斷了this是否為空,然后再判斷this的長(zhǎng)度。根據(jù)我們上面講的擴(kuò)展函數(shù)的本質(zhì),我們可以很好的理解,為什么null可以調(diào)用這個(gè)方法的原因。因?yàn)樯厦娴拇a轉(zhuǎn)為Java代碼后是這樣子的。
public
static
final
boolean
isNullOrEmpty(@Nullable
CharSequence
$this$isNullOrEmpty)
{
int
$i$f$isNullOrEmpty
=
0;
return
$this$isNullOrEmpty
==
null
||
$this$isNullOrEmpty.length()
==
0;
}我們?cè)谟胣ull調(diào)用這個(gè)擴(kuò)展方法時(shí),其實(shí)是將null作為一個(gè)參數(shù)傳入這個(gè)方法中,先判斷參數(shù)是否為null,再進(jìn)行下一步判斷,這當(dāng)然不會(huì)崩潰。擴(kuò)展不能真正的修改他們所擴(kuò)展的類。通過定義一個(gè)擴(kuò)展,你并沒有在一個(gè)類中插入新成員,僅僅是可以通過該類型的變量用點(diǎn)表達(dá)式去調(diào)用這個(gè)新函數(shù),并將自身作為參數(shù)傳入。擴(kuò)展屬性擴(kuò)展屬性和擴(kuò)展函數(shù)類似,再舉上面Person的例子,我們對(duì)Person類稍作修改,為其增加birthdayYear字段,表示其出生的年份。class
Person(val
name:
String,
val
birthdayYear:
Int)
{
fun
eat()
{
Log.i(name,
"I'm
going
to
eat")
}
fun
sleep()
{
Log.i(name,
"I'm
going
to
sleep")
}
}我們現(xiàn)在要為Person增加年齡age的屬性,但是不改Person類,怎么實(shí)現(xiàn)呢。和擴(kuò)展函數(shù)一樣,在其他文件中聲明如下。const
val
currentYear
=
2019
val
Person.age:
Int
get()
=
currentYear
-
this.birthdayYear我們通過當(dāng)前年份減去生日年份計(jì)算出Person的年齡??梢钥吹剑琣ge是一個(gè)屬性,而不是方法。這樣我們就為Person增加了一個(gè)擴(kuò)展屬性??梢钥纯此D(zhuǎn)化為Java代碼后的樣子,和擴(kuò)展函數(shù)沒啥區(qū)別。@Metadata(
mv
=
{1,
1,
15},
bv
=
{1,
0,
3},
k
=
2,
d1
=
{"\u0000\u0010\n\u0000\n\u0002\u0010\b\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0003\"\u000e\u0010\u0000\u001a\u00020\u0001X\u0086T¢\u0006\u0002\n\u0000\"\u0015\u0010\u0002\u001a\u00020\u0001*\u00020\u00038F¢\u0006\u0006\u001a\u0004\b\u0004\u0010\u0005¨\u0006\u0006"},
d2
=
{"currentYear",
"",
"age",
"Lcom/chaochaowu/kotlinextension/Person;",
"getAge",
"(Lcom/chaochaowu/kotlinextension/Person;)I",
"app_debug"}
)
public
final
class
PersonExtensionsKt
{
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年綠色食品認(rèn)證員質(zhì)量安全評(píng)估測(cè)試試卷及答案
- 全民消防安全知識(shí)試題及答案
- 2025年化工安全培訓(xùn)考試題及答案(附化工安全總結(jié))
- 水利工程安全監(jiān)測(cè)及管理流程
- 職業(yè)技能培訓(xùn)效果評(píng)估與反饋
- 制造業(yè)車間安全檢查表生產(chǎn)設(shè)備標(biāo)準(zhǔn)化版
- 建筑工程索賠報(bào)告寫作及案例
- 土地復(fù)墾過程中的環(huán)保措施總結(jié)報(bào)告
- 企業(yè)員工培訓(xùn)方案范本
- 健康安全環(huán)保的承諾函(7篇)
- 揮發(fā)性有機(jī)物(VOCs)執(zhí)法監(jiān)測(cè)能力建設(shè)項(xiàng)目可行性實(shí)施方案
- 工程施工月報(bào)表
- 鍋爐外部檢驗(yàn)報(bào)告
- GB/T 3098.6-2023緊固件機(jī)械性能不銹鋼螺栓、螺釘和螺柱
- 音標(biāo)拼讀練習(xí)(彩色版)
- GB/T 6672-2001塑料薄膜和薄片厚度測(cè)定機(jī)械測(cè)量法
- GA/T 952-2011法庭科學(xué)機(jī)動(dòng)車發(fā)動(dòng)機(jī)號(hào)碼和車架號(hào)碼檢驗(yàn)規(guī)程
- GA/T 172-2005金屬手銬
- 線段的垂直平分線和角平分線的復(fù)習(xí)(適合各種版本)課件
- 5Why分析法(經(jīng)典完整版)課件
- 2021年成都市《住宅物業(yè)服務(wù)等級(jí)規(guī)范》
評(píng)論
0/150
提交評(píng)論