Next page | Contents page |

Inheritance can be bad for you

A good example of bad inheritance is provided in the standard API by java.util.Stack. It represents a Last In First Out (LIFO) stack - useful for nested processing (put things on a stack as you go down, get them off again on the way back up). For this purpose it really needs just 3 methods:

It is like a stack of plates:

In the API documentation for java.util.Stack you can see that it inherits like this:

Further down you discover that there are the 3 methods we need plus a probably useful empty () but also a gratuitous search () (encouraging you to do things you really should not). But much worse are all the methods inherited from (legacy) Vector, enabling you to abuse the Stack as if it were any old list. None of these should ever be used on a LIFO stack: THIS IS BAD DESIGN.

A better Stack

Use composition rather than inheritance:

public class Stack<E>	// Does not extend anything 
{
   private java.util.LinkedList<E> list;

   public Stack () { list = new java.util.LinkedList<E> (); }
   public boolean isEmpty () { return 0 == list.size (); }
   public E peek () { return list.getLast (); }
   public E pop () { return list.removeLast (); }
   public void push (E obj) { list.add (obj); }
}

The list is private: none of its behaviour is available to users of Stack so the Stack can only be manipulated the way it should be.

This is an example of the adapter pattern, enabling re-use of a class (LinkedList here) by presenting a different interface to the clients.

UML class diagrams

Composition

Rather than inheritance

Composition or aggregation?

UML terminology:

It's composition if, when the containing object is copied or dies, the contained object is also copied or dies. UML:

It's aggregation if the contained object is not copied (or survives), because it is also used by other objects. UML:

The generic term is association, which also covers other kinds of relationships between classes. Eg, class A creates instances of class B. UML:

or

(if there is no clear direction).

Further points on inheritance

Inheritance makes maintenance harder than if composition is used instead. Changes in the behaviour available in a parent class are likely to cause changes to behaviour of all sub-classes.

Inheritance is not always bad - use it if there is genuinely an "is a" relationship.

Next page | Contents page |