Kotlin基礎十二
拓展方法和屬性
在Kotlin中,有一個很神奇的特性,就是可以爲已經存在的類添加方法和屬性。具體實現也很簡單:
fun String.lastChar(): Char = this.get(this.length - 1)
fun main(args: Array<String>) {
println("Hello, Kotlin".lastChar())
}
//result:
n
Process finished with exit code 0
String
類原本並沒有lastChar()
方法,但我們可以像上面這樣拓展了String
類,爲其拓展了這個方法,我們就可以像使用String
類的其他方法一樣使用我們拓展的方法。
我們看這個方法是怎樣聲明的:
fun String.lastChar(): Char = this.get(this.length - 1)
要拓展的類,在這裏也就是String
,被稱爲receiver type
,this
就是receiver object
,這和聲明一個函數幾乎沒什麼差別,先是fun
關鍵字,然後是要拓展的類的類型,緊接着是.
加方法名,再聲明返回值,receiver object
(可以省略this
),其他的和函數的聲明沒什麼太大的差別。
需要注意的是,拓展方法無法訪問類的private
和protected
成員。
導入extension function
import Kt03.lastChar
fun main(args: Array<String>) {
println("import extension function".lastChar())
}
拓展方法不會自動導入,需自己動手。導入拓展的方法也很簡單,就是import packageName.extensionFunction
.
如果使用import packageName.*
,將會導入這個包裏面的全部函數、類和拓展方法。
你還可以用as
關鍵字來命名別名,就像python那樣:import packageName.extensionFunction as ef
.
import Kt03.lastChar as last
拓展方法具有靜態屬性,這意味着不能在子類中覆寫父類的拓展方法。
從Java調用Kotlin的拓展方法
Kotlin的拓展方法轉成Java時會被編譯成Java的靜態方法,因此調用Kotlin的拓展方法在Java中就像調用靜態方法那樣簡單:
import Kt03.Kt35Kt;
public class CallExtensionFunc {
public static void main(String...agrs) {
System.out.println(Kt35Kt.lastChar("Java"));
}
}
//result:
a
Process finished with exit code 0
拓展屬性
拓展屬性和拓展方法幾乎沒什麼差別:
fun String.lastChar(): Char = get(length - 1)
val String.lastChar: Char get() = get(length-1)
fun main(args: Array<String>) {
println("Hello, Kotlin".lastChar())
println("Hello, world".lastChar)
}
//result:
n
d
Process finished with exit code 0
需要注意的是get()
是必須被聲明和定義的。因爲在拓展屬性中,編譯器不會再幫你自動生成getter
和setter
了。
在Kotlin中,之所以kotlin的集合比Java的集合多了更多的操作,就是因爲Kotlin有拓展方法這個特性,像Kotlin集合中的last
、max
這些方法就是拓展方法。