Kotlin中的sam(函數(shù)式接口)詳解
用lambda表達(dá)式去表示java中的匿名類實例
在使用java去給一個按鈕設(shè)置監(jiān)聽我們通常會通過創(chuàng)建匿名類實例,如下
Button.setOnClickListener(new OnClickListener()){ @Override public void onClick(View v){ Toast.makeText(this,"Hello World",Toast.LENGTH_LONG).show() } }
在kotlin我們可以通過傳遞一個lambda表達(dá)式去代替這個實例
btn_test.setOnClickListener { view : View -> Toast.makeText(this,"Hello World",Toast.LENGTH_LONG).show() }
可以以這種方式去實現(xiàn)的原因是OnClickListener接口只有一個抽象方法,這種接口在kotlin中被當(dāng)作函數(shù)式接口,或者SAM接口,SAM代表單抽象方法,類似的還有像Runnable和Callable這樣的函數(shù)式接口.
把lambda當(dāng)作參數(shù)傳遞給Java方法
我們在java中定義一個
void postponeComputation(int delay,Runnable computation){ }
然后使用lambda表達(dá)式去傳遞Runnable這個參數(shù)
postponeComputation(1000){ print("hello world") }
注意這個lambda實參編譯器會自動把它轉(zhuǎn)換成一個Runnable實例. 這種調(diào)用方式效果和顯示的實現(xiàn)一個Runnable匿名對象一樣
postponeComputation(1000,object : Runnable{ override fun run(){ println(42) } })
但實際不一樣的是,每次調(diào)用這種語句會重復(fù)創(chuàng)建Runnable對象,而使用lambda表達(dá)式作為實參如果沒有訪問任何來自定義它的函數(shù)變量那么只會創(chuàng)建一個對象.
如果想要完全等價需要這樣去定義
val runnable = Runaable{ println(42) } fun handleComputation(){ postponeComputation(1000,runnable) }
另外如果從包圍它的作用域中捕捉了變量,每次調(diào)用就不會重用同一個實例了, 如下調(diào)用每次都會使用一個新的Runnable實例.
fun handleComputation(id : String){ postponeComputation(1000){println(id)} }
實際上從kotlin1.0起, 每個lambda都會被編譯成一個匿名類,如果lambda捕捉了變量,每個被捕捉的變量會在匿名類中有對應(yīng)的字段.
SAM構(gòu)造方法:顯式地把lambda轉(zhuǎn)換成函數(shù)式接口.
在有的方法中需要返回一個函數(shù)式接口,不能返回一個lambda, 可以用SAM構(gòu)造方法把它包裝起來. 如下
fun createAllDoneRunable() : Runnable{ return Runnable{ println(“All done”) } }
SAM函數(shù)名稱和底層函數(shù)式接口的名稱一樣. SAM構(gòu)造方法只接收一個參數(shù)-一個被用作函數(shù)式接口單抽象方法體的lambda,并返回一個接口類的實例.
另外除了返回值通過lambda創(chuàng)建函數(shù)式接口外,也可以把lambda生成的函數(shù)式接口放在一個變量中,如下
val listener = OnClickListener{ view -> val text = when(view.id){ R.id.button1 -> “First button” R.id.button2 -> “Second button” else -> “Unknown button" } toast(text) } button1.setOnClickListener(listener) button2.setOnClickListener(listener)
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Ubutu1604安裝colmap實現(xiàn)方法詳細(xì)教程
這篇文章主要介紹了Ubutu1604安裝colmap實現(xiàn)方法詳細(xì)教程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-11-11Android實現(xiàn)EditText圖文混合插入上傳功能
這篇文章主要為大家詳細(xì)介紹了Android實現(xiàn)EditText圖文混合插入上傳功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-08-08Android操作系統(tǒng)的架構(gòu)設(shè)計分析
這篇文章主要介紹了Android操作系統(tǒng)的架構(gòu)設(shè)計分析,Android系統(tǒng)架構(gòu)分為Linux內(nèi)核驅(qū)動、C/C ++框架、Java框架、Java應(yīng)用程序,本文分別講解了它的作用,需要的朋友可以參考下2015-06-06android 觸屏的震動響應(yīng)接口調(diào)用方法
android 相關(guān)開發(fā)過程中,經(jīng)常會使用到觸屏的震動響應(yīng)接口,為此本文列出以下方法,想要了解的朋友可以參考下2012-11-11Android 下的 QuickJS Binding 庫特性使用詳解
這篇文章主要介紹了Android 下的 QuickJS Binding 庫特性使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09Android 通過API獲取數(shù)據(jù)庫中的圖片文件方式
這篇文章主要介紹了Android 通過API獲取數(shù)據(jù)庫中的圖片文件方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03詳解Android使用Socket對大文件進(jìn)行加密傳輸
這篇文章主要介紹了詳解Android使用Socket對大文件進(jìn)行加密傳輸,使用Socket進(jìn)行文件傳輸過程時,需要先進(jìn)行加密,有興趣的可以了解一下。2017-01-01