扩展函数在Kotlin中有着重要的应用,我们使用的Kotlin为我们提供的许多方便的方法都是通过扩展方法实现的,那么扩展函数究竟长啥样呢?我们来看看
所谓扩展,即能过扩展一个类的新功能而无需继承或使用像装饰者这样的任何类型的设计模式。
Kotlin支持扩展函数和扩展属性,这里我们先看看扩展函数长啥样吧。
/**
* Performs the given [action] on each element.
*/
public inline fun <T> Array<out T>.forEach(action: (T) -> Unit): Unit {
for (element in this) action(element)
}
这是我们最常见的forEach,这是Kotlin对Array的扩展方法,使用起来很方便。当然这只是其中的一种形式,它还有许多重载。
声明一个扩展函数,我们需要用一个接受者类型 也就是被扩展的类型来作为他的前缀。
上面forEach中,有一些其它的概念,如inline、T、out,我们暂时可以不关注。
扩展函数,在函数体中,this关键字对应接收者对象(传过来的点符号前面的对象)
action:(T) -> Unit //声明了一个函数,(T) -> Unit表示函数类型,T是泛型参数
扩展静态解析的
通过扩展函数,我们可以很方便的未一个类添加扩展功能,但是需要注意,扩展并不是真正的修改了它们所扩展的类。
定义一个扩展,我们并没有在一个类中插入新成员,仅仅是可以通过该类型的变量用点表达式去调用这个新函数。
事实上,同过查看字节码,我们很容易可以发现,接收者对象其实最终会作为第一参数传入扩展函数中。
因此,我们需要注意一下几点:
- 调用的扩展函数是由函数调用所在的表达式的类型来决定,而不是由表达式运行时求职结果决定。
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"
}
- 当一个类的成员函数和扩展函数相同时(同名,参数相同),这种情况总是优先取成员函数。