“仅在有意义的地方子类”的详细解释是什么?

Cod*_*ver 4 java inheritance api-design subclass

来自名为“如何设计良好的 API 及其重要性”的演示文稿

我被困在演示文稿的第 25 页,其中写着:

为了便于实现,公共类不应子类化其他公共类

它给了我们一个例子(Java语法):

Bad:    Properties extends Hashtable 
        Stack extends Vector

Good:   Set extends Collection
Run Code Online (Sandbox Code Playgroud)

但为什么这些例子有好有坏呢?

Gio*_*tta 5

因为 aProperties 不是 a Hashtable,并且它们不应该互换使用,即,您不希望用户Properties在他们只需要的地方使用HashtableStack与vs相同Vector

好的设计应该力求 API 的简单性。如果您正在设计Stack,您基本上应该只提供pushpop方法。公开继承Vector泄漏用户不需要知道的实现细节。除了混乱之外,这意味着您永远无法更改实现!因此,如果明天Vector被弃用(我相信实际上是在这一点上),您仍然会坚持Stack使用它,因为您的客户可能会期望它。更改实现会违反向后兼容性,这是另一个设计目标。

请注意,上面的示例不是随机的。和Vector都是Hashtable被认为已过时的类(请参阅此处此处的最后评论)。这些类存在一些设计缺陷,并被ArrayListHashMap或类似的其他类取代。这使得从它们继承的类也过时了。如果您使用组合而不是继承,则可以轻松地将Vector和替换Hashtable为其现代对应项,而不会影响任何用户。

另一方面,Set 是一个 Collection. 也就是说,如果某些代码指定它需要某种Collection,则用户可以自由提供 a Set(或 aList或其他)。如果对此集合应提供的内容没有特定要求(例如无随机访问),这将为 API 提供更大的灵活性。