CodeGroover
CodeGroover

Reputation: 2187

What is detailed explanation of argument "Subclass Only Where It Makes Sense"?

From presentation called How to Design a Good API and Why it Matters

I'm stuck on page 25 of the presentation in which says:

Public classes should not subclass other public classes for ease of implementation

And it gave us an examples (Java syntax):

Bad:    Properties extends Hashtable 
        Stack extends Vector

Good:   Set extends Collection

But why are those examples bad and good?

Upvotes: 4

Views: 100

Answers (3)

John Bollinger
John Bollinger

Reputation: 180181

Bloch is distinguishing inheritance of interface from inheritance of implementation.

It is impossible to know from a slide deck what he said at this point in his presentation, but a typical argument for avoiding one public class inheriting from another is that it permanently ties the subclass to the superclass's implementation. For example, Properties cannot ever implement its property storage in HashMap form or any other form other than a HashTable.

Another argument is that it couples the classes too tightly together. Modifications that would be beneficial to the superclass can break the subclass, or render its behavior worse.

A third argument is that the subclass inherits methods from the superclass that may not make sense for it, or may do so in the future if the methods are added to the superclass. For example, because Stack extends Vector, it is possible to examine arbitrary elements below the top one, and even to add, remove, or modify internal elements. This one applies to some extent also to inheritance of interface, but it is not usually as much of a problem in that case.

The first two arguments remain applicable to some extent even when the super- and subclasses have an is-a relationship.

Upvotes: 0

Giovanni Botta
Giovanni Botta

Reputation: 9816

Because a Properties is not a Hashtable, and they shouldn't be used interchangeably, i.e., you don't want users to use Properties where they only need Hashtable. Same for Stack vs Vector.

Good design should strive for simplicity of API. If you are designing a Stack, you should basically only provide the push and pop methods. Publicly inheriting from Vector leaks an implementation detail that the user does not need to know. Beside the confusion, this means you can never change the implementation! So if tomorrow Vector gets deprecated (which I believe it actually is at this point), you are still stuck with a Stack that uses it because your clients might expect it. Changing the implementation would violate backward compatibility, which is another design goal.

Note that the example above is not random. Both Vector and Hashtable are classes that are considered obsolete (see the last comments here and here). These classes have some design flaws and were replaced by ArrayList and HashMap or similar others. This makes classes that inherit from them obsolete as well. If instead of inheriting you used composition, you could easily swap Vector and Hashtable for their modern counterparts without affecting any user.

On the other hand, Set is a Collection. That is, if some code specifies that it needs some kind of Collection, the user is free to provide a Set (or a List or whatever). This gives more flexibility to the API if there are no specific requirements on what this collection should provide (no random access for example).

Upvotes: 5

Jon S.
Jon S.

Reputation: 1378

Inheriting from a class is typically thought of as implementing an "is-a" relationship.

Is a collection of properties a hashtable? No, not really. The hashtable is an implementation detail, not a fundamental characteristic of "Properties". This implies that you should be using aggregation, like so:

class Properties {
    private HashTable mPropertyTable;
}

The same goes for Stack and Vector. A Stack isn't a special kind of Vector, so the Vector should be a member of the Stack used for implementation only.

Contrast this with Set deriving from Collection. Is a Set a type of Collection? Yes, it is, so in this case inheritance makes sense.

Upvotes: 0

Related Questions