长大后想做什么?做回小孩!

0%

Java多继承问题

长期被诟病的多继承,不仅仅是Java语言所头疼的问题。多继承是一个较为复杂的设计问题,使用中很容易出现致命的问题。像Goto语句一样,利弊交织。

很多技术伟人已经提供了多套解决方案例如:传统模式(深度优先,每个类以第一次出现的位置为准),但是遇到菱形继承就bug了。new-style class曾应用于python2.2中,和Java使用的策略很相似仍然使用深度优先搜索、从左向右,但是每个类选择其最后一次出现的位置,解决了菱形继承的bug但是交叉继承依旧bug。 C3算法提供了一个基于层级计算的线性MRO算法,被称为C3,整体上比较合理了。 在2012年被加入了Dylan语言,2007年加入了Python2.3后来又被应用于更多的语言,虽然计算问题解决了,但是依然存在一些难以理解的问题:

mNbgw4.jpg

引见: python-history知乎python.org

Java编程中可选的解决方法

原则上Java是不允许多继承的,但是在编程中依然存在一些方法来模拟实现多继承:

多层继承

ABCD四个类,B继承A,C继承B,D继承C,然后通过D的对象调用父类们的方法。

建议一般不要超过三次,缺点很明显,代码冗余,一点也不优雅。

内部类

不写演示了,相对于多层继承,就是把ABC三个类的继承工作放到D类中,用A1、B1、C3三个内部类分别继承ABC三个类,然后写A1、B1、C1调用方法,直接new内部类对象调用其方法。

相对于多层继承,内部类继承的方式将所有的继承都放在一个类中,阅读性增加。但是缺点依然没有太好的改善:代码冗余,依然不够优雅。

接口(推荐)

Java的接口继承功能,既实现了静态语言的多重继承性,又避免了多重继承的数据构造的冲突和类层次的复杂性。
但是,我们并不能说接口是解决问题的完美方案。接口也有不能共享实现的缺点。
本来只是为了跨越继承层次来共享代码,现在却需要另外生成一个独立对象,而且每次方法调用都要委派给这个对象,这实在是不太合理,而且执行的效率也不高。

——《松本行弘的程序世界》

松本行弘在Ruby中选择了Mix-in方案来解决多继承问题。

通过松本行弘的话大概明白了接口继承的部分优劣性,Java中也确实是这么做的,接口继承虽然将问题抛给了使用者大大增加了工作量,但是也切实有效的避免了很大一部分问题。有取必有舍

一个类只能extends一个父类,但可以implements多个接口。java通过使用接口的概念来取代C++中多继承。与此同时,一个接口则可以同时extends多个接口,却不能implements任何接口。因而,Java中的接口是支持多继承的。

接口实现多继承还有一个好处:这样可以把子类利用多态赋给多个父类(接口),而把主要的方法使用组合封装起来而避免多次实现接口的方法。