對于一個(gè)聲明了多個(gè)方法的接口,我們使用的時(shí)候有時(shí)僅僅關(guān)注于幾個(gè)關(guān)鍵方法,并不需要實(shí)現(xiàn)所有的怀估。可是由于接口調(diào)用的語法限制合搅,使得我們不得不在代碼中也顯示聲明實(shí)現(xiàn)了那些我們不關(guān)心的方法多搀。在java中也有簡化接口調(diào)用的方式,比如安卓中ViewPager監(jiān)聽頁面切換時(shí)的接口PageChangeListener历筝,官方提供了簡單類: ViewPager.SimpleOnPageChangeListener來簡化調(diào)用酗昼。
對于Kotlin來說,可以類似使用java的方式梳猪,來實(shí)現(xiàn)多函數(shù)接口的簡化調(diào)用麻削,只是要用到object關(guān)鍵字且代碼仍會(huì)較多。這里春弥,由于Kotlin的語法更為靈活呛哟,去實(shí)現(xiàn)這種調(diào)用應(yīng)該有其特色的方式,使得代碼更少匿沛,且更加具有張力扫责。
來個(gè)小例子,先簡單介紹類似java實(shí)現(xiàn)多函數(shù)接口的簡化調(diào)用逃呼,一是展示什么是簡化接口調(diào)用鳖孤,二是做對比。這里得例子都用kotlin寫的抡笼。
- 1.聲明接口CallBack 和調(diào)用類Worker
interface CallBack {
fun onSuccess(str: String)
fun onFailure(code: Int)
}
class Worker {
var callback: CallBack? = null
fun done(str: String) {
callback?.onSuccess(str)
}
fun fail(code: Int) {
callback?.onFailure(code)
}
fun setCallBack(lis: CallBack) {
callback = lis;
}
}
- 2.直接調(diào)用接口苏揣,使用了object關(guān)鍵字 ,此時(shí)假設(shè)不關(guān)心success方法推姻,但必須顯示聲明平匈。
Worker().apply {
setCallBack(object : CallBack {
override fun onSuccess(str: String) {
}
override fun onFailure(code: Int) {
toast("$code")
}
})
}.fail(110)
//結(jié)果:吐司:110
- 3.Java風(fēng)格簡化調(diào)用,聲明簡化類SimCallBack
public class SimCallBack implements CallBack{
@Override
public void onSuccess(@NotNull String str) {
}
@Override
public void onFailure(int code) {
}
}
- 4.Java風(fēng)格簡化調(diào)用的展示,不關(guān)心的onSuccess不用再顯示聲明
Worker().apply {
setCallBack(object : SimCallBack() {
override fun onFailure(code: Int) {
super.onFailure(code)
toast("$code")
}
})
}.fail(110)
上述帶著濃濃java味道的調(diào)用增炭,不僅代碼風(fēng)格比較混雜忍燥,而且代碼顯得冗余。重點(diǎn)來了隙姿,Kotlin怎么去克服上面兩點(diǎn)呢梅垄。看例子孟辑。
- 1.還是CallBack接口哎甲,不過其簡化類需要用Kotlin風(fēng)格來做:
class SimpleCallBack : CallBack{
private var _OnSucess: ((str: String) -> Unit)? = null
fun success(listener: (str: String) -> Unit) {
_OnSucess = listener
}
override fun onSuccess(str: String) {
_OnSucess?.invoke(str)
}
private var _OnFailure: ((code: Int) -> Unit)? = null
override fun onFailure(code: Int) {
_OnFailure?.invoke(code)
}
fun fail(listener: (code: Int) -> Unit) {
_OnFailure = listener
}
}
聲明了兩個(gè)函數(shù)類型變量 _OnSucess和 _OnFailure,作用就是內(nèi)部將原來的大接口CallBack分解饲嗽。然后聲明了對應(yīng)的方法success和fail炭玫,目的是給變量小接口賦值。接著就是原接口方法的處理貌虾,比如原接口方法onSuccess(str: String)的操作 _OnSucess?.invoke(str)吞加,目的是實(shí)現(xiàn)接口回調(diào)結(jié)果的轉(zhuǎn)移。做這些尽狠,目的就是為以后的簡化調(diào)用做準(zhǔn)備衔憨。
- 2.調(diào)用類Worker 也是要進(jìn)行處理一下的,代碼基本同原來的那些袄膏,只是增加了以下方法践图。注意,若不是為了兼容java方式沉馆,原setCallBack可以不再聲明码党,直接賦值就好,由此斥黑,新增方法可以看做是原setCallBack方法的替換揖盘。
fun setCallBacker(listener: SimpleCallBack.() -> Unit) {
var ca = SimpleCallBack()
ca.listener()
setCallBack(ca)
}
注意名稱。本方法接受一個(gè)函數(shù)參數(shù)锌奴,方法的作用是內(nèi)部生成一個(gè)簡化接口對象SimpleCallBack兽狭,然后再讓調(diào)用類注冊到接口。然后執(zhí)行傳進(jìn)來的函數(shù)參數(shù)鹿蜀,為什么要這樣呢箕慧,是為了使用kotlin語法中靈活的閉包{}。另外茴恰,配上強(qiáng)大的函數(shù)擴(kuò)展語法销钝,不改變原有類,增加個(gè)這種方法還是比較容易的琐簇。
- 3.最后看看調(diào)用方式吧:
Worker().apply {
setCallBacker {
success { toast(it) }
fail { }//若不需要,可以不顯示聲明
}
}.done("完成")
//結(jié)果:吐司:完成
最后結(jié)果可以看出,當(dāng)調(diào)用多函數(shù)接口CallBack時(shí)婉商,并不需要再聲明接口似忧,而是直接在閉包里聲明想要使用的方法,然后在對應(yīng)的方法閉包里執(zhí)行操作即可丈秩。風(fēng)格完全是kotlin盯捌,且使用特別簡便。
作者劉咸尚