上節(jié)我們講了Kotlin的函數(shù)式編程朋凉,本章我們來講一下kotlin的擴展函數(shù)以及與Java不同的接口回調(diào)墓毒。
一团秽、擴展函數(shù)的定義及原理
擴展函數(shù)其實就是相當(dāng)于Java中的靜態(tài)方法踪栋,這個靜態(tài)方法的參數(shù)是接收者類型的對象眷唉,那么利用這個對象就可以訪問這個類中的成員屬性和方法了,并且最后會返回該對象本身摩泪,這樣在外部感覺和使用類的成員函數(shù)是一樣的捏检,但和成員函數(shù)還是不同的,成員函數(shù)是真正的在該類內(nèi)部,而擴展函數(shù)只不過是偽裝為內(nèi)部調(diào)用,也就無法訪問類的成員屬性和方法茸苇。
二、擴展函數(shù)的使用
只需要把擴展的類或者接口名稱漩氨,放到即將要添加的函數(shù)名前面。這個類或者名稱就叫做接收者類型,類的名稱與函數(shù)之間用"."調(diào)用連接。this指代的就是接收者對象,它可以訪問擴展的這個類可訪問的方法和屬性赴魁。
//創(chuàng)建一個data的類,data也是kotlin的關(guān)鍵字潘拱,內(nèi)部幫我們實現(xiàn)了get,set方法
data class UserBean(var name:String,var age:Int)
//創(chuàng)建擴展函數(shù)
fun UserBean.print(){
println("姓名:$name 年齡:$age")
}
//調(diào)用
val user = UserBean("Bob",21)
user.print()
那既然有擴展函數(shù)辑鲤,肯定也得有擴展屬性,我們來看下怎么實現(xiàn)
data class UserBean(var name:String,var age:Int)
var UserBean.realName:String
get() = realName
set(newName) {
realName = newName
}
#################################################################
前邊講了擴展函數(shù)和擴展屬性,下面我們來學(xué)一些Kotlin的接口回調(diào)和java有什么不同
在java中實現(xiàn)
//創(chuàng)建一個接口
public interface CallBackJava {
void print(String name,int age);
}
//創(chuàng)建業(yè)務(wù)邏輯層
public class Presser {
private CallBackJava callBack;
private void init() {
//todo
//接口回調(diào)
if (callBack != null) callBack.print("Bob", 21);
}
//設(shè)置callback
public void setCallBack(CallBackJava callBack) {
this.callBack = callBack;
}
}
//調(diào)用層調(diào)用
Presser presser = new Presser();
presser.setCallBack(new CallBackJava() {
@Override
public void print(String name, int age) {
System.out.println(name+age);
}
});
在kotlin中這樣實現(xiàn)
interface CallBack {
fun print(name:String,age:Int)
}
class Presser {
private var callBack: CallBackJava? = null
private fun init() {
callBack?.print("Bob", 21)
}
fun setCallBack(callBack: CallBackJava?) {
this.callBack = callBack
}
}
//調(diào)用
val presser = Presser()
presser.setCallBack { name, age -> println("$name$age") }
what???這不是和java一樣嗎惑芭,也沒顯得多簡潔啊逃沿,稍等我們可以這樣優(yōu)化,Kotlin不是可以將函數(shù)賦值給變量嗎哄尔,我們省略創(chuàng)建接口富拗,利用變量來代替葵擎,通過invoke調(diào)用,這樣是不是更簡潔了呢這也是利用了kotlin函數(shù)式編程特性的具體應(yīng)用
class Presser {
private fun init() {
callBack.invoke("Bob", 21)
}
fun setCallBack(callBack: (name: String, age: Int) -> Unit) {
this.callBack = callBack
}
private lateinit var callBack: (name: String, age: Int) -> Unit
}
//調(diào)用
val presser = Presser()
presser.setCallBack { name, age ->
println("$name$age")
}
總結(jié):當(dāng)然冠摄,如果是接口中多個回調(diào),就沒辦法用函數(shù)式改造了,如果整合成一個惰瓜,通過定義type類型來操作也是可以流强。