首發于公眾號: DSGtalk1989
8.Kotlin 擴展
-
擴展函數
我們可以在任何時刻,任何地方,去幫類添加擴展函數,形式就是如下
fun 擴展類.擴展方法(){ println("123456") }
然后能在任何地方任何時刻都能使用這個擴展的方法。
如果擴展函數和成員函數同名,那么優先使用成員函數。
可以擴展一個空的對象,空的對象我們使用
Any?
去表示fun Any?.newString(): String { if (this == null) return "null" // 空檢測之后,“this”會自動轉換為非空類型,所以下面的 toString() // 解析為 Any 類的成員函數 return toString() }
這樣一來我們在任何時刻去調用
toString()
方法的話都不會出現空指針的異常 -
擴展屬性
我們還能針對屬性做擴展,比如我們想要為
List
類加一個屬性lastIndex
,代表列中的最后一個值的索引。val <T> List<T>.lastIndex : Int get() = size - 1
擴展屬性只能用
val
來形容,即擴展的屬性只能讀取,不能修改。 -
伴生對象的擴展
伴生對象是我們在kotlin中一般用來處理單例的方式,可以簡要的在此做一下說明,我們主要使用
companion
關鍵字來處理//kt文件 class TestInstance{ companion object } //decompile java public final class TestInstance { public static final TestInstance.Companion Companion = new TestInstance.Companion((DefaultConstructorMarker)null); public static final class Companion { private Companion() { } public Companion(DefaultConstructorMarker $constructor_marker) { this(); } } }
就是比較經典的單例模式,在kotlin中我們可以直接通過
TestInstance.Companion
的方式去訪問這個類的單例,我們可以理解成就是TestInstance.getInstance()
方法半生對象的擴展如下:
fun TestInstance.Companion.newFun(a : String) : Int{ val b = a + "1" return b.length } val TestInstance.Companion.property : Int get() = 1
-
擴展的作用域
作用域較廣,跨包名調用也可以直接通過
import
的方式直接使用。 -
擴展中遇到的各種沖突或同名問題
-
情況1 同名擴展函數
如果出現了同名擴展函數,則調用內部函數,不調用擴展函數
fun D.toString(){ Log.e("extension", "toString") }
并沒有用,最終會調用類
D
自己的toString
方法 -
情況2 擴展函數中調用內部同名函數
擴展函數中出現了擴展類中和本類中都有的函數,以擴展類中的為主,若想使用本類中的函數,需要加上標注
this@ClassName
class D { fun hello(){} } class C { fun hello(){} fun D.newFun(){ hello() this@C.hello() } }
第一個
hello
方法用的是D
中的hello
,如果想使用C
中的hello
的話需要加上this@C
-
情況3 繼承中出現的擴展
首先,我們應該很容易理解,如下這種情況,即參數類型是
D
,所以用的應該是D的擴展函數foo()
open class D { } class D1 : D() { } open class C { open fun D.foo() { println("D.foo in C") } open fun D1.foo() { println("D1.foo in C") } fun caller(d: D) { d.foo() // 調用擴展函數 } }
如果
C1
繼承了C
,同時復寫了擴展函數,如下:class C1 : C() { override fun D.foo() { println("D.foo in C1") } override fun D1.foo() { println("D1.foo in C1") } }
那么調用
C1
的caller
方法,無論傳D
類型還是D1
類型,最終打印的都是println("D.foo in C1")
-
Kotlin學習筆記之 13 基礎操作符run、with、let、also、apply