Avoid concrete base classes

From CSSEMediaWiki
(Difference between revisions)
Jump to: navigation, search
Line 1: Line 1:
'''Riel's heuristic #5.7''': All base classes should be abstract classes.
+
'''Riel's heuristic #5.7''': All base classes should be abstract classes. Riel derived this from [[Johnson and Foote 1988]] - [[The top of the class hierarchy should be abstract]]
  
 
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]].
 
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]].
Line 24: Line 24:
 
* [[Eliminate irrelevant classes]]
 
* [[Eliminate irrelevant classes]]
 
* [[Avoid inheritance for implementation]]
 
* [[Avoid inheritance for implementation]]
 +
* [[Johnson and Foote 1988]]

Revision as of 07:36, 6 October 2008

Riel's heuristic #5.7: All base classes should be abstract classes. Riel derived this from Johnson and Foote 1988 - The top of the class hierarchy should be abstract

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