最近我一直在告诉记者,在面向对象的编程一个很好的做法, 你应该总是让您的类继承 。 我真的不这么认为,但我有我的心中没有了坚实的论据。
阻止继承的真实世界的例子 :
- 没有C ++类STL(专门类模板)允许继承(具有非虚拟析构函数)。
- Java有它的
final
一个适用于许多标准组件,如类修饰符java.lang.String
。
我认为可能的原因有:
- 安全 ,因为子类可能访问敏感的内部。 (我不这么认为 - 他们不会访问私有成员。)
- 性能方面 ,由于一个子类可以弄乱我们通过覆盖一些成员函数高效的实现。 (孩子们将不会覆盖非虚函数)。
- 为了强制组合物过度继承 。 (我完全同意。在不需要的时候我们不应该赞成继承。)
所以我的问题是: 在什么情况下应该怎么故意阻止继承?
事实上,我尝试的做法遵循,那乔希布洛赫建议,在他的有效的Java书,正是你一直在说的一个逆规则:除非你有想过继承,设计你的类继承,并记录你的类必须如何被继承,你应该总是禁用继承。
我建议你阅读有效的Java本章(你会不会后悔买它),然后显示给谁告诉你这个规则的人。
最明显的原因,不允许继承是不可改变的。 不可变的对象是使用简单(只有一个状态),可以被缓存,许多对象之间共享的,并且本质上是线程安全的。 如果类是否可继承,任何人都可以扩展类,并使其可变通过添加可变属性。
那么对于初学者,只是不允许继承,如果你是积极的,你不希望别人能扩展您的类。 防止继承为了微不足道的原因(如性能)通常不推荐,因为代码重用往往胜过小性能提升,你可以通过标记你的类实现final
。
话虽这么说,这里有几个例子,当你可能需要明确阻止继承:
你正在编写一个商业的,封闭源代码级的,你不希望人们能够改变功能的路线。 这是一个很好的理由,以避免类继承,因为你不希望有后来给它的支持,如果人们已经推翻了你的方法和/或延长你的班,都在抱怨,他们所得到意想不到的效果。
您正在设计一个不可变的类。 通过标记类final
,你是防止危害您的类的不可变行为的子类。 举例来说,如果你被允许继承String
,别人可以使自己的实现,使String
s到被修改。 现在没有代码,需要一个类型String
可以是某些物体是不可变的。
要强制组成了继承 。 当你想避免类之间的紧耦合(即你不想要的高度依赖于彼此类组)这是可取的。
你想通过编译器内联鼓励。 标记类和方法最终可能导致小的性能提升,因为这将确保Java没有来查找正确的类方法来调用在运行时的对象。 非final方法被标记为虚拟的,这样它们可以适当延长或如果需要的话,最后的方法可以直接挂在类内联汇编。 请注意,性能增益可以通过这样实现往往是微不足道的(尤其是如果你的类的方法是大)。
只是我的0.02在这...
一类允许继承允许人们应对不可预见的问题。 (例如,经常发生在回报率的的monkeypatching。它可以是丑陋,但它的现实与迂腐)。 话虽如此,我不是没来由的继承的忠实粉丝。 基和亚类之间的关系可以是易碎的。 深继承层次是很难神交。
一个情况下,我能想到的,不允许继承执行不变性。 这是搞什么的Java String类非常重要的。