2.Kotlin-扩展函数

为MutableList类扩展一个swap函数:
    fun MutableList<Int>.swap(index1: Int, index2: Int) {
        val tmp = this[index1]  //this: 当前MutableList对象 
        this[index1] = this[index2]
        this[index2] = tmp
    }    
对MutableList对象调用swap函数:
    val list = mutableListOf(1, 2, 3)
    list.swap(0, 2)

MutableList泛化类型:
    //为在表达式中使用泛型,要在函数名前添加泛型参数!
    fun <T> MutableList<T>.swap(index1: Int, index2: Int) {
        val tmp = this[index1]
        this[index1] = this[index2]
        this[index2] = tmp
    }

扩展函数是静态解析的
扩展函数是静态解析的,并不是接收者类型的虚拟成员,在调用扩展函数时,具体被调用的的是哪一个函数,由调用函数的的对象表达式来决定的,而不是动态的类型决定的:
1.调用是由对象声明类型决定,而不是由对象实际类型决定!
    open class C
    class D: C()
    fun C.foo() = "c"
    fun D.foo() = "d"
    fun printFoo(c: C) {
        println(c.foo()) //扩展函数是静态解析的,不是虚函数(即没有多态)
    }
    fun main(args: Array<String>) {
        printFoo(D()) //输出"c",扩展函数调用只取决于参数c的声明类型 
    }

2.类的成员函数和扩展函数-同名同参数:
    class C {
        fun foo() { println("member") }
    }
    fun C.foo() {
        println("extension") 
    }
    fun main(args: Array<String>) {
        val c = C()
        println(c.foo()) //输出“member”
    }

3.类的成员函数和扩展函数-同名不同参数:
    class C {
        fun foo() { println("member") }
    }
    fun C.foo(i: Int) {
        println("extension")
    }
    fun main(args: Array<String>) {
        val c = C()
        println(c.foo(2)) //输出"extension"
    }



在一个类内部可为另一个类声明扩展,   
扩展声明所在的类称为分发接收者(dispatch receiver),
扩展函数调用所在类称为扩展接收者(extension receiver)

1.定义
    class D { //扩展接收者(extension receiver)
        fun f() { …… }
    }

    class C { //分发接收者(dispatch receiver)
        fun f() { …… }

        fun D.foo() {
           [email protected]() //分发接收者 C.f()
           f()        //扩展接收者 D.f()
        }

        fun call(d: D) {
            d.foo()   //调用扩展函数
        }
    }

2.继承-覆盖
成员扩展可声明为open,并在子类中被覆盖,
对分发接收者是虚拟的(多态),但对扩展接收者是静态的!
    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 call(d: D) {
            d.foo()   // 调用扩展函数
        }
    }
    class C1 : C() {
        override fun D.foo() {
            println("D.foo in C1")
        }
        override fun D1.foo() {
            println("D1.foo in C1")
        }
    }
    C().call(D())   // 输出 "D.foo in C"
    C().call(D1())  // 输出 "D.foo in C", 扩展接收者静态解析(非多态)
    C1().call(D())  // 输出 "D.foo in C1",分发接收者虚拟解析(多态)


猜你喜欢

转载自blog.csdn.net/zmesky/article/details/80984402