Kotlin 笔记 扩展

扩展(extension)是指向已有的类中添加函数

扩展函数

定义扩展函数时,在函数前面加上要扩展类的名字,以下代码向MutableList添加了swap方法

fun MutableList.swap(index1: Int, index2: Int) {
    val tmp = this[index1] // 'this' corresponds to the list
    this[index1] = this[index2]
    this[index2] = tmp
}

this在extension函数中指代扩展类的实例

Extensions是静态调用的,也就是说调用哪个类的extension函数是在编译时决定的,而不是动态运行时调用的

open class C

class D: C()

fun C.foo() = "c"

fun D.foo() = "d"

fun printFoo(c: C) {
    println(c.foo()) \\ "c"
}

printFoo(D())

如果extension函数和成员函数冲突,那么会调用成员函数

extension函数可以overload成员函数

扩展类可以是null

fun Any?.toString(): String {
    if (this == null) return "null"
    // after the null check, 'this' is autocast to a non-null type, so the toString() below
    // resolves to the member function of the Any class
    return toString()
}

扩展属性

val  List.lastIndex: Int 
  get() = size - 1

扩展属性不能初始化,只能定义getter和setter方法

Companion Object

可以对Companion Object定义扩展函数和扩展属性

在函数内部定义扩展

class D {
    fun bar() { ... }
}

class C {
    fun baz() { ... }

    fun D.foo() {
        bar()   // calls D.bar
        baz()   // calls C.baz
    }

    fun caller(d: D) {
        d.foo()   // call the extension function
    }
}

如果扩展类和定义类的函数名冲突,会优先使用扩展类的函数,如果要使用定义类的函数,需要使用qualified this

class C {
    fun D.foo() {
        toString()         // calls D.toString()
        [email protected]()  // calls C.toString()
    }

扩展还可以用open修饰,在子类中可以override

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()   // call the extension function
    }
}

class C1 : C() {
    override fun D.foo() {
        println("D.foo in C1")
    }

    override fun D1.foo() {
        println("D1.foo in C1")
    }
}

你可能感兴趣的:(Kotlin 笔记 扩展)