Kotlin擴展詳解

kotlin的擴展詳解

擴展函數

class ExtensionTest{ //擴展接收者類
    fun add(a:Int,b:Int)=a+b
}
fun ExtensionTest.substract(a:Int,b:Int)=a-b //擴展函數
fun main(args: Array<String>) {
    val extensionTest=ExtensionTest()
    extensionTest.add(2,5)
    extensionTest.substract(5,0)
}

擴展函數的解析是靜態的

  • 擴展本身並不會真正修改目標類,也就是說它並不會在目標類中插入新的屬性和方法。
  • 擴展函數的解析是靜態分發的,即不支持多態,調用只取決於對象的聲明類型。
  • 調用是由對象聲明類型所決定的,而不是由對象的實際類型所決定。
open class AA
class BB:AA()
fun AA.a()="a"
fun BB.b()="b"
fun myprint(aa:AA){
    println(aa.a())
}
fun main(args: Array<String>) {
    myprint(AA()) //打印是“a”
    myprint(BB()) //打印還是“a”,,如果是java肯定是“b”,這就是調用只取決於對象的聲明類型,不是初始的實際類型。

}

伴生對象擴展函數

class MyProperty
 val MyProperty.name:String
     get()="hello
     
fun main(args: Array<String>) {
    var myProperty=MyProperty()
    println(myProperty.name)
}

擴展的作用域(類似於java的裝飾模式)

  • 擴展函數所定義在的類實例叫做分發接收者(dispatch receiver)
  • 擴展函數所擴展的那個類的實例叫做擴展接收者(extension receiver)
  • 當以上兩個名字出現衝突時,擴展接收者的優先級最高
class AA{  //擴展接收者類
    fun method(){
        println("AA method")
    }
}
class BB{ //分發接收者
    fun method2(){
    }
    fun AA.hello(){
        method() //擴展的是AA,當然能調用AA類裏的方法
        method2() //同一個類中當然能調用同級的方法
    }
    fun word(aa:AA){
        aa.hello() //聲明的對象是AA,hello方法是AA的擴展方法,當然能調用
    }
    fun AA.output(){
        println(toString())//調用的是AA類裏的tostring方法,因爲擴展接收者的優先級最高
        println([email protected]())//調用的是BB類裏的tostring方法
    }
    fun test(){
        val aa=AA()
        aa.output() //擴展函數還是要擴展類的實例調用。
    }
}
fun main(args: Array<String>) {
    BB().test()
}

跳轉到官方kotlin擴展

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章