《Kotlin核心编程》 ——3.3.3 内部类解决多继承问题的方案

举报
华章计算机 发表于 2020/02/21 22:48:53 2020/02/21
【摘要】 本节书摘来自华章计算机《Kotlin核心编程》 —— 书中第3章,第3.3.3节,作者是水滴技术团队 。

3.3.3 内部类解决多继承问题的方案

我们要探讨的第2种方式就是用内部类模拟多继承的效果。我们知道,在Java中可以将一个类的定义放在另一个类的定义内部,这就是内部类。由于内部类可以继承一个与外部类无关的类,所以这保证了内部类的独立性,我们可以用它的这个特性来尝试解决多继承的问题。

在探讨这个问题之前,我们有必要来了解一下Kotlin中内部类的语法。如你所知,Java的内部类定义非常直观,我们只要在一个类内部再定义一个类,那么这个类就是内部类了,如:

public class OuterJava {

    private String name = "This is Java's inner class syntax.";

 

    class InnerJava {  //内部类

        public void printName()

        {

            System.out.println(name);

        }

    }

}

现在我们尝试用类似的Kotlin代码来改写这段代码,看看有没有类似的效果。

class OuterKotlin {

    val name = "This is not Kotlin's inner class syntax."

 

    class ErrorInnerKotlin { // 其实是嵌套类

        fun printName() {

            print("the name is $name") //error

        }

    }

}

// 运行结果

Error:(5, 32) Unresolved reference: name

怎么回事,这段代码竟然报错了?其实这里闹了乌龙,当前我们声明的并不是Kotlin中的内部类,而是嵌套类的语法。如果要在Kotlin中声明一个内部类,我们必须在这个类前面加一个inner关键字,就像这样子:

class OuterKotlin {

    val name = "This is truely Kotlin's inner class syntax."

 

    inner class InnerKotlin {

        fun printName() {

            print("the name is $name")

        }

    }

}

内部类vs嵌套类

众所周知,在Java中,我们通过在内部类的语法上增加一个static关键词,把它变成一个嵌套类。然而,Kotlin则是相反的思路,默认是一个嵌套类,必须加上inner关键字才是一个内部类,也就是说可以把静态的内部类看成嵌套类。

内部类和嵌套类有明显的差别,具体体现在:内部类包含着对其外部类实例的引用,在内部类中我们可以使用外部类中的属性,比如上面例子中的name属性;而嵌套类不包含对其外部类实例的引用,所以它无法调用其外部类的属性。

好了,在熟悉了内部类的语法之后,我们就回到之前的骡子的例子,然后用内部类来改写它。

open class Horse { //马

    fun runFast() {

        println("I can run fast")

    }

}

 

open class Donkey { //驴

    fun doLongTimeThing() {

        println("I can do some thing long time")

    }

}

 

class Mule {  //骡子

    fun runFast() {

        HorseC().runFast()

    }

 

    fun doLongTimeThing() {

        DonkeyC().doLongTimeThing()

    }

 

    private inner class HorseC : Horse()

    private inner class DonkeyC : Donkey()

}

通过这个修改后的例子可以发现:

1)我们可以在一个类内部定义多个内部类,每个内部类的实例都有自己的独立状态,它们与外部对象的信息相互独立;

2)通过让内部类HorseC、DonkeyC分别继承Horse和Donkey这两个外部类,我们就可以在Mule类中定义它们的实例对象,从而获得了Horse和Donkey两者不同的状态和行为;

3)我们可以利用private修饰内部类,使得其他类都不能访问内部类,具有非常良好的封装性。

因此,可以说在某些场合下,内部类确实是一种解决多继承非常好的思路。


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。