Avoid concrete base classes

From CSSEMediaWiki
Revision as of 00:50, 3 September 2008 by Elliot Fisher (Talk | contribs)
Jump to: navigation, search

Riel's heuristic #5.7: All base classes should be abstract classes.

Riel states that all base classes of an inheritance hierarchy should be abstract. Note that this does not mean that single classes with no inheritance hierarchy should be made abstract, as this would mean a concrete subclass would have to be created that adds no meaningful functionality - this violates Heuristic 3.7; Eliminate irrelevant classes.

This heuristic is a trade off between design complexity and flexibility. The example Riel gives (taken from the Object Oriented Design Heuristics book) is a FullEmployee class that inherits from a concrete NewEmployee class. It seems to tie in with Avoid inheritance for implementation. In this case we cannot add something to the NewEmployee class without it also being added (via inheritance) to the FullEmployee class.

5.7 example1.png


This problem can be avoided by recognising that a NewEmployee and a FullEmployee have something in common, which can be represented by an abstract base class that they both inherit from. The new design would be:

5.7 example2.png


The worst effect of violating this heuristic is that the name of the original concrete base class must be globally changed to the new abstract base class. This usually cannot be avoided as the name of the concrete base class is too specific for the abstract base class.

Abstract base classes should not always be used, however. The case when not to use an abstract base class is described in Heuristic 3.7, Eliminate irrelevant classes. Do not create an abstract base class if one of the concrete subclasses does not add any meaningful functionality, ie it would be an empty class with only inherited attributes. It can be hard to find a good balance between these two conflicting heuristics. Riel recommends finding the classes that are most likely to change, and to add irrelevant subclasses for these, leaving the other classes that are unlikely to change as inheriting from a concrete class. This minimizes the effect of having too many irrelevant classes in your design, and having too many potential global name changes for classes.


Discussion points: Have we got any examples of our own? Do we believe Riel?

See also

Personal tools