kotlin中的扩展函数,实际上是在自己的类中添加了一个static final方法,将需要扩展的类,在使用的时候作为第一个参数传入方法中,然后使用。比如:
在ExtensionTest.kt中的顶级函数
fun String.hello(str: String): String{
return "hello" + str + this.length
}
fun String.hello1(str: String): String{
return "hello$str"
}
经过反编译之后生成字节码如下:
public final class ExtensionTestKt {
@NotNull
public static final String hello(@NotNull String $receiver, @NotNull String str) {
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
Intrinsics.checkParameterIsNotNull(str, "str");
return "hello" + str + $receiver.length();
}
@NotNull
public static final String hello1(@NotNull String $receiver, @NotNull String str) {
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
Intrinsics.checkParameterIsNotNull(str, "str");
return "hello" + str;
}
}
这其实就变成了在ExtensionTestKt这个类中的两个static final方法,而原先对String类型进行扩展,其实就是将调用扩展函数的调用者作为函数的第一个参数传入。
kotlin中的扩展函数,实际上就是通过给类添加public static final函数的做法来实现,这样做可以减少utils类的使用
扩展函数是静态解析的,是采用静态分派的过程来处理。这意味着调用的扩展函数是由函数调用所在的表达式的类型来决定的, 而不是由表达式运行时求值结果决定的。这意思其实就是在使用该扩展函数的时候,如果类本身和其子类都进行了同一个函数的扩展,这函数是不会有重写关系的,在使用的时候,只会根据需要使用该方法的对象的实际类型来决定是调用了哪个,就是相当于调用静态方法。而不是动态分派。比如:
open class Shape
class Rectangle: Shape()
fun Shape.getName() = "Shape"
fun Rectangle.getName() = "Rectangle"
fun printClassName(s: Shape) {
println(s.getName())
}
printClassName(Rectangle())
这里的输出结果是Shape
其实很明显,因为扩展函数就是相当于一个静态方法,而调用静态方法是没有重写,所以子类并不会影响父类。
如果一个类定义有一个成员函数与一个扩展函数,而这两个函数又有相同的接收者类型、 相同的名字,并且都适用给定的参数,这种情况总是取成员函数。
class Example {
fun printFunctionType() { println("Class method") }
}
fun Example.printFunctionType() { println("Extension function") }
Example().printFunctionType()
这段代码输出“Class method”。
网友评论