Kotlin實現多函式介面的簡化呼叫
對於一個聲明瞭多個方法的介面,我們使用的時候有時僅僅關注於幾個關鍵方法,並不需要實現所有的。可是由於介面呼叫的語法限制,使得我們不得不在程式碼中也顯示宣告實現了那些我們不關心的方法。在java中也有簡化介面呼叫的方式,比如安卓中ViewPager監聽頁面切換時的介面PageChangeListener,官方提供了簡單類: ViewPager.SimpleOnPageChangeListener來簡化呼叫。
對於Kotlin來說,可以類似使用java的方式,來實現多函式介面的簡化呼叫,只是要用到object關鍵字且程式碼仍會較多。這裡,由於Kotlin的語法更為靈活,去實現這種呼叫應該有其特色的方式,使得程式碼更少,且更加具有張力。
來個小例子,先簡單介紹類似java實現多函式介面的簡化呼叫,一是展示什麼是簡化介面呼叫,二是做對比。這裡得例子都用kotlin寫的。
- 1.宣告介面CallBack 和呼叫類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.直接呼叫介面,使用了object關鍵字 ,此時假設不關心success方法,但必須顯示宣告。
Worker().apply {
setCallBack(object : CallBack {
override fun onSuccess(str: String) {
}
override fun onFailure(code: Int) {
toast("$code")
}
})
}.fail(110)
//結果:吐司:110
- 3.Java風格簡化呼叫,宣告簡化類SimCallBack
public class SimCallBack implements CallBack{
@Override
public void onSuccess(@NotNull String str) {
}
@Override
public void onFailure(int code) {
}
}
- 4.Java風格簡化呼叫的展示,不關心的onSuccess不用再顯示宣告
Worker().apply {
setCallBack(object : SimCallBack() {
override fun onFailure(code: Int) {
super.onFailure(code)
toast("$code")
}
})
}.fail(110)
上述帶著濃濃java味道的呼叫,不僅程式碼風格比較混雜,而且程式碼顯得冗餘。重點來了,Kotlin怎麼去克服上面兩點呢。看例子。
- 1.還是CallBack介面,不過其簡化類需要用Kotlin風格來做:
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
}
}
聲明瞭兩個函式型別變數 _OnSucess和 _OnFailure,作用就是內部將原來的大介面CallBack分解。然後聲明瞭對應的方法success和fail,目的是給變數小介面賦值。接著就是原介面方法的處理,比如原介面方法onSuccess(str: String)的操作 _OnSucess?.invoke(str),目的是實現介面回撥結果的轉移。做這些,目的就是為以後的簡化呼叫做準備。
- 2.呼叫類Worker 也是要進行處理一下的,程式碼基本同原來的那些,只是增加了以下方法。注意,若不是為了相容java方式,原setCallBack可以不再宣告,直接賦值就好,由此,新增方法可以看做是原setCallBack方法的替換。
fun setCallBacker(listener: SimpleCallBack.() -> Unit) {
var ca = SimpleCallBack()
ca.listener()
setCallBack(ca)
}
注意名稱。本方法接受一個函式引數,方法的作用是內部生成一個簡化介面物件SimpleCallBack,然後再讓呼叫類註冊到介面。然後執行傳進來的函式引數,為什麼要這樣呢,是為了使用kotlin語法中靈活的閉包{}。另外,配上強大的函式擴充套件語法,不改變原有類,增加個這種方法還是比較容易的。
- 3.最後看看呼叫方式吧:
Worker().apply {
setCallBacker {
success { toast(it) }
fail { }//若不需要,可以不顯示宣告
}
}.done("完成")
//結果:吐司:完成
最後結果可以看出,當呼叫多函式介面CallBack時,並不需要再宣告介面,而是直接在閉包裡宣告想要使用的方法,然後在對應的方法閉包裡執行操作即可。風格完全是kotlin,且使用特別簡便。
分享結束,希望對讀者有所幫助。
作者劉鹹尚