What are the negative aspects of Java class Stack inheriting from Vector?

Effective Java 2nd Edition, Item 16: Favor composition over inheritance:

Inheritance is appropriate only in circumstances where the subclass really is a subtype of the superclass. In other words, a class B should only extend a class A only if an “is-a” relationship exists between the two classes. If you are tempted to have a class B extend a class A, ask yourself this question: Is every B really an A? If you cannot truthfully answer yes to this question, B should not extend A. If the answer is no, it is often the case that B should contain a private instance of A and expose a smaller and simpler API; A is not an essential part of B, merely a detail of its implementation.

There are a number of obvious violations of this principle in the Java platform libraries. For example, a stack is not a vector, so Stack should not extend Vector. Similarly, a property list is not a hash table, so Properties should not extend Hashtable. In both cases, composition would have been preferrable.

The book goes in greater detail, and combined with Item 17: Design and document for inheritance or else prohibit it, advises against overuse and abuse of inheritance in your design.

Here’s a simple example that shows the problem of Stack allowing un-Stack-like behavior:

    Stack<String> stack = new Stack<String>();
    stack.push("1");
    stack.push("2");
    stack.push("3");
    stack.insertElementAt("squeeze me in!", 1);
    while (!stack.isEmpty()) {
        System.out.println(stack.pop());
    }
    // prints "3", "2", "squeeze me in!", "1"

This is a gross violation of the stack abstract data type.

See also

Leave a Comment