1、继承的原本目的是逐步细化,而不是为了提取共性
因为如果是为了提取共性,那多重继承就会成为主流。
2、多重继承
优点:对真实反映对象间关系。
缺点:关的关系过于复杂,不易理解,容易写“意大利面条程序”。
a、结构复杂化
b、优先顺序模糊
c、功能冲突:不同父类中有相同的方法时会产生冲突。
3、单一继承
优点:继承单纯,是明显的树结构。
缺点:很多继承无法表示,如ReadWriteStream要同时继承ReadStream和WriteStream才行。
4、什么才是完美
多重继承与单一继承各有利弊,引入受限制的多重继承是个好办法。
Java中它就是接口(interface),Lisp和Ruby中是Mixin。
5、继承的两种含义
类的继承包含两种含义。
a、“类有哪些方法”,这是规格的继承。
b、“类的方法是具体怎么执行的”,这是实现的继承。
静态语言中两者区别很重要。Java中实现的继承用extend类,属于单一继承。规格的继承用implements接口,属于多重继承。
6、接口的缺点
Java中用接口来实现多重继承,即变相实现了多重继承,又避免了多重继承带来的功能冲突和复杂性。但这不完美。
接口不能共享。如果想实现共享要用组合模式来调用别的类实现共通功能。很麻烦。
7、Mix-in
与静态语言Java不同,动态语言本来就没有规格继承这种概念。动态语言要实现的只有多重继承,因此用Java的接口对于动态语言不能解决任何问题。
Mix-in规则:
a、通常的继承用单一继承
b、第二个及两个以上的父类必须是Mix-in的抽象类。
Mix-in类是这样的抽象类:
a、不能单独生成实例
b、不能继承普通类
Ruby只支持Mix-in形式的多重继承,Mix-in的单位是模块(module)
8、两个误解
误解1、对象是对现实世界中具体物体的反映,继承是对物体分类的反映。
结构化编程实现了控制流程的结构化(抛弃goto),但此时要处理的数据还没有结构化,这就是面向对象的作用,即实现了要处理的数据的结构化。最终提高生产率。
最终所有面向对象编程语言都有以下共通功能:i、不需要知道内部的详细处理就可能进行操作(封装、数据抽象)
ii、根据不同的数据类型自动选择适当的方法(多态性)
所以面向对象是对结构化编程的扩展,对象是否是现实世界中具体物体的反映就不重要的。如字符串、数组等很多没有具体物体相对应。而且即使有对应,也只是描述现有物体部分概念而已。程序不需要实现所有功能,它只是处理抽象数据的。
类是对象的模板,包含两方法特性:类型(类的特征)+模块(即方法)。
继承是利用模块的手段。类之间会存在共同点。避免重复的方法是继承。
继承只不过是抽象的功能利用方法,不必牵强为“继承是对现实事物分类的反映”。
误解2、多重继承是不好的,而Mix-in却很好。
多重继承用得不好就会出问题,并不是本身不好。Mix-in只是实现多重继承的一个技巧而已。Java中接口实际上就是多重继承。