Multi-Inheritance Solutions For Kotlin

在很多实际业务中很有可能会面对一个问题:一个类的多继承.回手翻资料所有文档档案都会告诉你Java/Kotlin是不能多继承的,而多继承是实现在C++语言之中,由此C++也引出了一个所谓的经典的钻石问题,相关背景此处不再多述,有兴趣者可以翻阅相关资料.

好的,在Kotlin中要实现多继承那么我们就要借用它的多实现特性:

一. 接口实现多继承

interface Tiger{
    val name: String
    fun climbTree()
    fun colour() = "yellow and white"

}
interface Lion{
    fun eatMeat()
    fun colour() = "yellow"
}
class Tigon(override val name: String):Tiger,Lion{

    override fun climbTree() {
        println("it can climb tree")
    }
    override fun eatMeat() {
        println("it can eat meat")
    }
    override fun colour(): String { // here todo custom return value
        return super<Lion>.colour()
    }
}

Kotlin的super关键字可以指定继承那个父类接口的方法,这也是Java/Kotlin常用的方式;

执行测试结果:"yellow"

fun main() {
    println(Tigon("虎狮").colour())
}

二. 内部类实现多继承

open class Tiger(val name: String = ""){
    fun climbTree()="i can climb tree"

    fun colour() = "yellow and white"
}
open class Lion{
    fun eatMeat()="i can eat meat"

    fun colour() = "yellow"
}
class Tigon{
    fun climbTree()= Tiger1().climbTree()

    fun eatMeat() = Lion1().eatMeat()

    fun colour() = Tiger1().colour()
    private inner class Tiger1:Tiger()
    private inner class Lion1:Lion()
}

事实上,我们可以在一个类的内部定义多个内部类,而内部类与外部类的信息是相互独立的,并且我们可以用private关键字去修饰内部类,使得其他类都不能访问内部类,具有非常好的封装性.

执行测试结果:"yellow and white"

fun main() {
    println(Tigon().colour())
}

三. 委托实现多继承

interface ClimbTree{
    fun climbTree(): String
    fun colour(): String
}
interface EatMeat{
    fun eatMeat(): String
    fun colour(): String
}
open class Tiger: ClimbTree{
    override fun colour()  = "yellow and white"

    override fun climbTree() = "i can climb tree"
}
open class Lion: EatMeat{
    override fun colour() = "yellow"

    override fun eatMeat() = "i can eat meat"
}
class Tigon(val tiger: Tiger,val lion: Lion):ClimbTree by tiger,EatMeat by lion {
    override fun colour() = tiger.colour()
}

委托是Kotlin新引入的语法,如果您是一名C#开发者,您极有可能熟悉关键字delegate,他是一种特殊的类型,用于方法事件委托,在Kotlin中可以通过by关键字实现委托.例如经常会用到的延迟属性 by lazy ,除了这种内置行为外,还提供了一种可观察属性的行为,这就很像我们Java中所说的观察者模式.以后有条件我会单独开一篇,利用委托来改善观察者模式.

执行测试结果:"i can climb tree"
                       "yellow and white"

fun main() {
    val tiger = Tiger()
    val lion = Lion()
    val tigon = Tigon(tiger,lion)
    println(tigon.climbTree())
    println(tigon.colour())
}

事实上,当使用委托来实现多继承就必须强制覆写委托类中的相同名称接口,很多人会疑问这跟接口实现多继承极为相似,而且并没有简单多少东西;也似乎也跟组合相像,其实委托在我目前看来至少有两处优点:

         1. 接口是不能实现复杂逻辑的,且不赞成在接口中实现复杂的业务逻辑,上述委托虽说也是接口委托,但它是有具体的类去实                 现方法逻辑;

         2. 当我们需要继承一个类A,委托对象是B,在具体调用的时候并不是像组合一样A.B.methodB,而是直接调用A.methodB,这                   能更加直观的表达A所拥有的methodB的行为,故所谓所述观察者模式特征A类的methodB实际由B类methodB来完成.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值