程序员社区

Kotlin-类委托(delegation)

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中直接从语法角度就支持了委托,还是挺强大的。

Kotlin-类委托(delegation)插图
image-20210620223609705

MyClass类实现了MyInterface的接口,本来需要实现接口的myPrint 方法,但是我们通过构造器方法MyClass(myInterface: MyInterface) 传入了一个MyInterface接口的实现类,所以通过by myInterface 直接就可以不用override fun myPrint() 该方法直接调用了构造器传入的myInterfacemyPrint方法。

通过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() 方法,方法的实现体就是调用了构造方法传入的myInterfacemyPrint()方法

接下来再做一个实验,假如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
Kotlin-类委托(delegation)插图1
image-20210620224447144

这个委托背后的原理是啥呢?下面先用文字描述一下:“by关键字后面的对象实际上会被存储在类的内部,编译器则会将父接口中的所有方法都实现出来,并且将实现转移给委托对象来去进行。

Kotlin-类委托(delegation)插图2
image-20210620224554036
Kotlin-类委托(delegation)插图3
image-20210620224725850
赞(0) 打赏
未经允许不得转载:IDEA激活码 » Kotlin-类委托(delegation)

一个分享Java & Python知识的社区