一、擴展函數 擴展函數可以方便地給現有類增加屬性和方法而不改動類地代碼。 二、原理 fun String.addTo(s: String): String{ return this + s } 反編譯: @Metadata( mv = {1, 6, 0}, k = 2, d1 = {"\u0000\ ...
一、擴展函數
擴展函數可以方便地給現有類增加屬性和方法而不改動類地代碼。
二、原理
fun String.addTo(s: String): String{
return this + s
}
反編譯:
@Metadata(
mv = {1, 6, 0},
k = 2,
d1 = {"\u0000\n\n\u0000\n\u0002\u0010\u000e\n\u0002\b\u0002\u001a\u0012\u0010\u0000\u001a\u00020\u0001*\u00020\u00012\u0006\u0010\u0002\u001a\u00020\u0001¨\u0006\u0003"},
d2 = {"addTo", "", "s", "app_releaseFlavorDebug"}
)
public final class TestKt {
@NotNull
public static final String addTo(@NotNull String $this$addTo, @NotNull String s) {
Intrinsics.checkNotNullParameter($this$addTo, "$this$addTo");
Intrinsics.checkNotNullParameter(s, "s");
return $this$addTo + s;
}
}
可以看出擴展函數實際上是生成了一個靜態方法,並且將被擴展的類的對象傳進了函數中。
由此我們可以知道:
我們在擴展函數中可以訪問被擴展的類的函數與屬性,但是不能訪問私有的函數與屬性,其訪問許可權與對象訪問許可權一致。
三、擴展屬性
擴展屬性提供了一種方法能通過屬性語法進行訪問的API來擴展。儘管它們被叫做屬性,但是它們不能擁有任何狀態,它不能添加額外的欄位到現有的Java對象實例。
val String.lastChar: Char get() = this[length -1]
原理與擴展函數類似。
public static final char getLastChar(@NotNull String $this$lastChar) {
Intrinsics.checkNotNullParameter($this$lastChar, "$this$lastChar");
return $this$lastChar.charAt($this$lastChar.length() - 1);
}
四、伴生對象的擴展函數
class Test{
companion object{
}
}
fun Test.Companion.get() {
}
五、總結
1、我們在擴展函數中可以訪問被擴展的類的函數與屬性,但是不能訪問私有的函數與屬性,其訪問許可權與對象訪問許可權一致。
2、擴展函數不能被子類重寫。
3、擴展函數實際是一個靜態函數處於類的外部,而成員函數是類的內部函數。