扩展函数(Extension functions)
fun MutableList<Int>.swap(index1: Int, index2: Int) {
val tmp = this[index1] // 'this' corresponds to the list
this[index1] = this[index2]
this[index2] = tmp
}
其中this指向接收对象(receiver object),点号(“.”)前面的类型是接收类型(receiver type)。
泛型扩展函数:
fun <T> MutableList<T>.swap(index1: Int, index2: Int) {
val tmp = this[index1] // 'this' corresponds to the list
this[index1] = this[index2]
this[index2] = tmp
}
Extensions 并没有真正修改他们所扩展的class,只是使得新的函数可以使用点号进行调用。
为Companion object添加扩展
class MyClass {
companion object{}
}
fun MyClass.Companion.printCompanion() {
println("Companion")
}
fun main(args: Array<String>) {
MyClass.printCompanion(); //Companion
}
Extensions的作用域
一般情况下,extensions是在顶层定义的。
package org.example.declarations
fun List<String>.getLongestString() { /*...*/}
定义Extension函数的类实例称为dispatch receiver, dispatch receiver支持动态绑定;
Extension函数所在的Receiver type的实例称为extension receiver,
extension type只支持静态绑定。
如果需要在外部使用时,需要单独导入:
package org.example.usage
import org.example.declarations.getLongestString
fun main() {
val list = listOf("red", "green", "blue")
list.getLongestString()
}
Extensions可以定义在class的内部
class Host(val hostName: String) {
fun printHostName() {
print(hostName)
}
}
class Connection(val host: Host, val port: Int) {
fun printPort() {
print(port)
}
fun Host.printConnectionString() {
printHostName() // calls Host.printHostname()
print(":")
printPort() // calls Connection.printPort()
toString() //调用了Host的toString()方法
this@Connection.toString() //调用Connection的toString()方法
}
fun connect() {
host.printConnectionString()
}
}
扩展函数的重载
open class Base{}
class Derived : Base() {}
open class BaseCaller {
//定义Base的扩展函数
open fun Base.printFunctionInfo() {
println("Base extension function in BaseCaller")
}
//定义Derived的扩展函数
open fun Derived.printFunctionInfo() {
println("Derived extension function in BaseCaller")
}
fun call(b: Base) {
b.printFunctionInfo() // call the extension function
}
}
class DerivedCaller: BaseCaller() {
//重载Base的扩展函数
override fun Base.printFunctionInfo() {
println("Base extension function in DerivedCaller")
}
//重载Derived的扩展函数
override fun Derived.printFunctionInfo() {
println("Derived extension function in DerivedCaller")
}
}
fun main(args: Array<String>) {
BaseCaller().call(Base()) //Base extension function in BaseCaller
DerivedCaller().call(Base()) //Base extension function in DerivedCaller
DerivedCaller().call(Derived()) //Base extension function in DerivedCaller
}