Kotlin擴展函數

Kotlin擴展函數提供了一種向類「添加」方法而不繼承類或使用任何類型的設計模式的工具。 創建的擴展函數用作類中的常規函數。

擴展函數使用帶有方法名稱的前綴接收器類型聲明。

fun <class_name>.<method_name>()

在上面的聲明中,<class_name>是接收器類型,<method_name>()是擴展函數。

擴展函數聲明及用法示例

通常,從類外部調用已經在類中定義的所有方法。在下面的示例中,Student類聲明一個方法是Passed(),它通過創建Student類的student對象,並在main()函數調用。

假設想調用一個沒有在Student類中定義的方法(比如isExcellent())。 在這種情況下,在Student類之外創建一個函數(isExcellent())爲Student.isExcellent(),並從main()函數調用它。 聲明Student.isExcellent()函數稱爲擴展函數,其中Student類稱爲接收器類型。

class Student{
    fun isPassed(mark: Int): Boolean{
        return mark>40
    }
}
fun Student.isExcellent(mark: Int): Boolean{
    return mark > 90
}
fun main(args: Array<String>){
    val student = Student()
    val passingStatus = student.isPassed(55)
    println("學生通過狀態是: $passingStatus")

    val excellentStatus = student.isExcellent(95)
    println("學生優秀的狀態是:$excellentStatus")
}

執行上面示例代碼,得到以下結果 -

學生通過狀態是: true
學生優秀的狀態是:true

以上示例僅演示瞭如何聲明擴展函數。

Kotlin擴展函數示例

下面來看看另一個擴展函數的示例。 在這個例子中,我們使用swap()方法交換MutableList <>的元素。 但是,MutableList <>類在內部不提供swap()方法來交換元素。 爲此爲MutableList <>創建swap()擴展函數。

列表對象使用list.swap(0,2)函數調用擴展函數(MutableList <Int> .swap(index1:Int,index2:Int):MutableList <Int>).swap(0,2)swap(0,2)函數傳遞MutableList <Int> .swap(index1:Int,index2:Int):MutableList <Int>)擴展函數中列表的索引值。

fun MutableList<Int>.swap(index1: Int, index2: Int):MutableList<Int> {
    val tmp = this[index1] // 'this' represents to the list
    this[index1] = this[index2]
    this[index2] = tmp
    return this
}
fun main(args: Array<String>) {
    val list = mutableListOf(5,10,15)
    println("在交換列表之前 :$list")
    val result = list.swap(0, 2)
    println("在交換列表之後 :$result")
}

執行上面示例代碼,得到以下結果 -

在交換列表之前 :[5, 10, 15]
在交換列表之後 :[15, 10, 5]

擴展函數作爲可空接收器

擴展函數可以定義爲可空接收器類型。 即使對象值爲null,也可以通過對象變量調用此可空擴展函數。 在函數主體內使用this == null檢查對象的可爲空性。

下面是使用擴展函數作爲可空接收器重寫上面示例中的程序。

fun MutableList<Int>?.swap(index1: Int, index2: Int): Any {
    if (this == null) return "null"
    else  {
        val tmp = this[index1] // 'this' represents to the list
        this[index1] = this[index2]
        this[index2] = tmp
        return this
    }
}
fun main(args: Array<String>) {
    val list = mutableListOf(5,10,15)
    println("在交換列表之前 :$list")
    val result = list.swap(0, 2)
    println("在交換列表之後 :$result")
}

執行上面示例代碼,得到以下結果 -

在交換列表之前 :[5, 10, 15]
在交換列表之後 :[15, 10, 5]

Companion對象擴展

companion對象是在類中聲明並使用companion關鍵字標記的對象。 Companion對象用於直接使用類名稱調用類的成員函數(如java中的static關鍵字)。

包含companion對象的類也可以定義爲companion對象的擴展函數和屬性。

Companion對象的示例

在這個例子中,使用類名(MyClass)作爲限定符來調用在companion對象內聲明的create()函數。

class MyClass {
    companion object {
        fun create():String{
            return "調用創建 companion 對象的方法"
        }
    }
}
fun main(args: Array<String>){
    val instance = MyClass.create()
    println(instance)
}

執行上面示例代碼,得到以下結果 -

調用創建 companion 對象的方法

Companion對象擴展示例
下面來看看一個Companion對象擴展的例子。 使用類名作爲限定符來調用Companion對象擴展。

class MyClass {
    companion object {
        fun create(): String {
            return "調用 companion 對象的create方法"
        }
    }
}
fun MyClass.Companion.helloWorld() {
    println("執行 companion 對象的擴展")
}
fun main(args: Array<String>) {
    MyClass.helloWorld() // 在 companion 對象上聲明的擴展函數
}

執行上面示例代碼,得到以下結果 -

執行 companion 對象的擴展