詳解如何實(shí)現(xiàn)一個(gè)Kotlin函數(shù)類型
接口與函數(shù)類型
業(yè)務(wù)開發(fā)中,經(jīng)常會(huì)有實(shí)現(xiàn)一個(gè)函數(shù)式接口(即接口只有一個(gè)方法需要實(shí)現(xiàn))的場(chǎng)景,大家應(yīng)該都會(huì)不假思索的寫出如下代碼:
interface Callback { fun response(): String } class Achieve: Callback { override fun response(): String { return "" } }
這么寫當(dāng)然沒什么毛病,甚至為了讓kotlin支持對(duì)接口Callback
的SAM
轉(zhuǎn)換,你還可以在接口前面增加一個(gè)fun
修飾:
fun interface Callback { fun response() }
但是對(duì)于Kotlin而言,本身函數(shù)類型是可以被實(shí)現(xiàn)的,也就是說我們可以使用函數(shù)類型替換函數(shù)式接口,讓子類去實(shí)現(xiàn),代碼如下:
class Achieve: () -> String { override fun invoke(): String { return "" } }
這種實(shí)現(xiàn)函數(shù)類型的類需要重寫的方法都是invoke()
,方法返回值類型對(duì)應(yīng)的就是函數(shù)類型的返回值類型。
這種寫法我在LeakCanary
的源碼中就看到了應(yīng)用,比如監(jiān)聽Fragment
是否銷毀的類AndroidOFragmentDestroyWatcher
:
在這里寫下我對(duì)這兩種方式優(yōu)缺點(diǎn)的比較:
1.函數(shù)類型相比較于接口去實(shí)現(xiàn)的優(yōu)點(diǎn)如下:
參數(shù)類型更加直觀
某個(gè)類實(shí)現(xiàn)了函數(shù)類型,能直觀的看到這個(gè)函數(shù)類型需要傳入的參數(shù)有哪些,是什么類型,返回值又是什么類型,而如果實(shí)現(xiàn)了一個(gè)接口,一般大家都習(xí)慣跳轉(zhuǎn)到接口定義的地方看接口方法的實(shí)現(xiàn),所以這一點(diǎn)函數(shù)類型會(huì)更加方便些
檢索更方便
函數(shù)類型需要重寫的方法名一定叫invoke
,所以如果我需要看下某個(gè)實(shí)現(xiàn)類對(duì)重寫方法的具體實(shí)現(xiàn)邏輯,直接在當(dāng)前類中搜索invoke
關(guān)鍵字定位到這個(gè)方法即可;而如果是一個(gè)接口接口,我得跳轉(zhuǎn)到接口的定義的地方看接口方法名是什么,才能去實(shí)現(xiàn)類中去搜索,所以在這點(diǎn)上函數(shù)類型會(huì)更加方便些
2.函數(shù)類型相比較于接口去實(shí)現(xiàn)的缺點(diǎn)如下:
函數(shù)類型語(yǔ)義性會(huì)比較差:
畢竟定義的接口名一般是和業(yè)務(wù)進(jìn)行綁定的,能大概知道這個(gè)接口是干啥用的,更加清晰直觀,當(dāng)然這個(gè)問題我們可以使用typealias
解決,但就會(huì)失去上面參數(shù)類型更加直觀的優(yōu)點(diǎn)
多態(tài)性會(huì)比較差(自己編的,不知道合不合理)
比如如果定義的一個(gè)接口去實(shí)現(xiàn),我們很容易實(shí)現(xiàn)下面這種功能:
fun test(achieve: Achieve) { if (achieve is Callback) { //實(shí)現(xiàn)某些邏輯 } }
而如果使用函數(shù)類型去實(shí)現(xiàn)這種邏輯:
看起來是不是很奇怪,而且對(duì)于很多需要重寫的方法簽名都是相同的(方法參數(shù)和返回值都是相同的),根本無(wú)法實(shí)現(xiàn)這種功能,具體的看下面一點(diǎn)的描述。
無(wú)法實(shí)現(xiàn)多個(gè)相同的函數(shù)類型
業(yè)務(wù)場(chǎng)景中也存在實(shí)現(xiàn)多個(gè)接口,并且接口定義的方法參數(shù)和返回值類型都是相同的,比如下面:
fun interface Callback { fun response(): String } fun interface Callback2 { fun response2(): String } class Achieve2: Callback, Callback2 { override fun response(): String { return "" } override fun response2(): String { return "" } }
如果使用函數(shù)類型根本無(wú)法實(shí)現(xiàn)上面的這種多個(gè)接口實(shí)現(xiàn)的功能:
直接進(jìn)行報(bào)錯(cuò)。
總結(jié)
不管是實(shí)現(xiàn)函數(shù)類型還是接口,兩者都各有其優(yōu)缺點(diǎn),大家需要根據(jù)業(yè)務(wù)場(chǎng)景進(jìn)行具體的選擇
到此這篇關(guān)于詳解如何實(shí)現(xiàn)一個(gè)Kotlin函數(shù)類型的文章就介紹到這了,更多相關(guān)Kotlin函數(shù)類型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
另外兩種Android沉浸式狀態(tài)欄實(shí)現(xiàn)思路
這篇文章主要為大家介紹了另外兩種Android沉浸式狀態(tài)欄實(shí)現(xiàn)思路,android5.0及以后版本都支持給狀態(tài)欄著色,而目前android主流版本還是4.4,想要深入了解的朋友可以參考一下2016-01-01Android自定義RecyclerView實(shí)現(xiàn)不固定刻度的刻度尺
這篇文章主要為大家詳細(xì)介紹了Android自定義RecyclerView實(shí)現(xiàn)不固定刻度的刻度尺,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07基于Android自定義控件實(shí)現(xiàn)刮刮樂效果
這篇文章主要介紹了基于Android自定義控件實(shí)現(xiàn)刮刮樂效果 的相關(guān)資料,需要的朋友可以參考下2015-12-12android 調(diào)用系統(tǒng)的照相機(jī)和圖庫(kù)實(shí)例詳解
android手機(jī)有自帶的照相機(jī)和圖庫(kù),我們做的項(xiàng)目中有時(shí)用到上傳圖片到服務(wù)器,今天做了一個(gè)項(xiàng)目用到這個(gè)功能,所以把我的代碼記錄下來和大家分享,有需求的朋友可以參考下2012-12-12Android編程實(shí)現(xiàn)canvas繪制餅狀統(tǒng)計(jì)圖功能示例【自動(dòng)適應(yīng)條目數(shù)量與大小】
這篇文章主要介紹了Android編程實(shí)現(xiàn)canvas繪制餅狀統(tǒng)計(jì)圖功能,可實(shí)現(xiàn)自動(dòng)適應(yīng)條目數(shù)量與大小的功能,涉及Android基于canvas的圖形繪制相關(guān)操作技巧,需要的朋友可以參考下2017-01-01Android實(shí)現(xiàn)定時(shí)任務(wù)及鬧鐘
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)定時(shí)任務(wù)及鬧鐘,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06Android控件之ScrollView用法實(shí)例分析
這篇文章主要介紹了Android控件之ScrollView用法,以完整實(shí)例形式較為詳細(xì)的分析了ScrollView控件滾動(dòng)顯示的實(shí)現(xiàn)技巧,需要的朋友可以參考下2015-09-09