继承的动机

Favor Composition over Inheritance.
“多用组合,少用继承”
—— The 10 Object-Oriented Design Principles
—— 面向对象的十大设计原则

作为面向对象三大特性之一的继承,被业界归纳的原则怼成这个样子,是人性的扭曲还是道德的沦丧?

从系统层面分析,公有成员是一个类的义务,私有成员则是一个类的权利。

继承的时候,实际上是继承了基类所有的义务,而没有继承一个类的权利。

特别地,保护成员,将作为义务(公有继承),还是作为权利(私有继承),亦或是保留争议(保护继承)以待后人?

以基类的视角看,它可以要求自己不被继承,但它并没有选择谁可以继承它的权利。

继承,完完全全是子类自身的意愿。无利不继承。当然,所造成的后果子类也要承担才是。

福兮祸之所依,祸兮福之所倚。一体两面,有利有弊。

子类自动随基类的变化而变化,往好了说叫做省事,自动按照默认情况实现;往坏了说叫做波及:

在基类变化的时候,子类会受到波及

这一点光靠完全重写(Complete Override)也是无法完全封装变化的,当基类新增公有成员的时候,子类没有任何手段可以自行阻止变化。

(但是通过反射/元编程机制还是做得到的,但在这种情况下,类已经不是一个静态的东西了)

所以大家都不喜欢继承。

因为其实从代码重用的角度看,它的灵活性远不及组合;从另外一个角度说,继承就是需要重写(Override)的,不然我们直接用基类不就好了?

继承的使用面很窄,但我们还是会用,在特定的问题上,继承显然比组合要优雅的多:

我,学生,是一个人。

我难道非得在“学生”对象里组合一个“人”的对象吗?

所以说,一切遵循语义约束(is-a),切不可妄下断言。

我们都在断章取义,原文,明确地提到,如果你只是想代码重用,那么就组合吧,别用继承。

我们却只抓着 “Favor Composition over Inheritance” 当作真言铭记在心。