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(this@BB.toString())//调用的是BB类里的tostring方法
}
fun test(){
val aa=AA()
aa.output() //扩展函数还是要扩展类的实例调用。
}
}
fun main(args: Array<String>) {
BB().test()
}