Kotlin-类委托(delegation)
我们用Java可以实现委托的功能,但是在Kotlin这个语言直接就已经支持了这个东东,这个在Java是不存在的,所谓委托很好理解:本来叫A去做事,而A自己不去做它将其委托给B去做。下面先来看一下类委托:
interface MyInterface {
fun myPrint()
}
class MyInterfaceImpl(val str: String) : MyInterface {
override fun myPrint() {
println("welcome " + str)
}
}
class MyClass(myInterface: MyInterface) : MyInterface by myInterface //委托类,没有类体
fun main(args: Array<String>) {
val myInterfaceImpl = MyInterfaceImpl("zhangsan")
MyClass(myInterfaceImpl).myPrint()
}
RUN> ??????
welcome zhangsan Process finished with exit code 0
要是在Java中我们还得传递引用自己来写逻辑,而在Kotlin中直接从语法角度就支持了委托,还是挺强大的。
MyClass类实现了MyInterface的接口,本来需要实现接口的myPrint
方法,但是我们通过构造器方法MyClass(myInterface: MyInterface)
传入了一个MyInterface
接口的实现类,所以通过by myInterface
直接就可以不用override fun myPrint()
该方法直接调用了构造器传入的myInterface
的myPrint
方法。
通过show kotlin bytecode 可以看到
public final class MyClass implements MyInterface {
// $FF: synthetic field
private final MyInterface $$delegate_0;
public MyClass(@NotNull MyInterface myInterface) {
Intrinsics.checkNotNullParameter(myInterface, "myInterface");
super();
this.$$delegate_0 = myInterface;
}
public void myPrint() {
this.$$delegate_0.myPrint();
}
}
MyClass
的java类implements MyInterface
实现了myPrint()
方法,方法的实现体就是调用了构造方法传入的myInterface
的myPrint()
方法
接下来再做一个实验,假如MyClass自己也定义了一个相同的myPrint(),那结果如何呢?下面试一下:
interface MyInterface {
fun myPrint()
}
class MyInterfaceImpl(val str: String) : MyInterface {
override fun myPrint() {
println("welcome " + str)
}
}
class MyClass(myInterface: MyInterface) : MyInterface by myInterface {
override fun myPrint() {
println("hello world")
}
}
fun main(args: Array<String>) {
val myInterfaceImpl = MyInterfaceImpl("zhangsan")
MyClass(myInterfaceImpl).myPrint()
}
RUN> ?♀️?♀️?♀️?♀️?♀️?♀️
hello world Process finished with exit code 0
这个委托背后的原理是啥呢?下面先用文字描述一下:“by关键字后面的对象实际上会被存储在类的内部,编译器则会将父接口中的所有方法都实现出来,并且将实现转移给委托对象来去进行。