接口实现多继承

  1. interface Flyer {
  2. fun fly()
  3. fun kind() = "flying Flyer"
  4. }
  5. interface Animal {
  6. val name: String
  7. fun eat()
  8. fun kind() = "flying animals"
  9. }
  10. class Bird(override val name: String) : Flyer, Animal {
  11. override fun fly() {
  12. println("I can fly")
  13. }
  14. override fun kind(): String {
  15. // 通过super调用某个父类
  16. return super<Flyer>.kind()
  17. }
  18. override fun eat() {
  19. println("I can eat")
  20. }
  21. }
  22. fun main() {
  23. Bird("AAA").fly()
  24. Bird("AAA").eat()
  25. Bird("AAA").kind()
  26. }

使用内部类实现多继承

// 使用内部类实现多继承
open class Horse {
    fun runFast() {
        println("I can run fast")
    }
}

open class Donkey {
    fun doLongTimeThing() {
        println("I can do something long time")
    }
}

class Mule {
    fun runFast() {
        HoeseC().runFast()
    }

    fun doLongTimeThing() {
        DonkeyC().doLongTimeThing()
    }

    // 定义多个内部类来实现多继承,每个内部类的实例都有自己独立的状态,它们与外部对象的信息相互独立
    private inner class HoeseC : Horse()
    private inner class DonkeyC : Donkey()
}

fun main() {
    Mule().doLongTimeThing()
    Mule().runFast()
}

使用内部类实现多继承

interface CanFly {
    fun fly()
}

interface CanEat {
    fun eat()
}

open class Flyer : CanFly {
    override fun fly() {
        println("I can Fly")
    }
}

open class Animal : CanEat {
    override fun eat() {
        println("I can Eat")
    }
}

class Bird(flyer: Flyer, animal: Animal) : CanFly by flyer, CanEat by animal {

}

fun main() {
    val flyer = Flyer()
    val animal = Animal()

    val bird = Bird(flyer, animal)
    bird.eat()
    bird.fly()
}

反编译后得字节码,可以看到,委托实现的Bird 实际上还是实现了CanFly和CanEat接口,然后通过Field delegate_0:LFlyer和Field delegate_1:LAnimal成员变量去调用代理对象的方法。

Compiled from "Bird.kt"
public final class Bird implements CanFly,CanEat {
  public Bird(Flyer, Animal);
    Code:
       0: aload_1
       1: ldc           #13                 // String flyer
       3: invokestatic  #19                 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_2
       7: ldc           #21                 // String animal
       9: invokestatic  #19                 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
      12: aload_0
      13: invokespecial #24                 // Method java/lang/Object."<init>":()V
      16: aload_0
      17: aload_1
      18: putfield      #28                 // Field $$delegate_0:LFlyer;
      21: aload_0
      22: aload_2
      23: putfield      #32                 // Field $$delegate_1:LAnimal;
      26: return

  public void fly();
    Code:
       0: aload_0
       1: getfield      #28                 // Field $$delegate_0:LFlyer;
       4: invokevirtual #39                 // Method Flyer.fly:()V
       7: return

  public void eat();
    Code:
       0: aload_0
       1: getfield      #32                 // Field $$delegate_1:LAnimal;
       4: invokevirtual #44                 // Method Animal.eat:()V
       7: return
}