Abstract and Concrete Classes
In this section we are going to introduce the concept of abstract classes and illustrate the differences between these and concrete classes.
All classes can be designated as either abstract or concrete. Concrete is the default. This means that the class can have (direct) instances. In contrast, abstract means that a class cannot have its own (direct) instances. Abstract classes exist purely to generalize common behaviour that would otherwise be duplicated across (sub)classes. We'll illustrate this with the following diagram.
In the above diagram there is an abstract class called Employee. In UML, the name of an abstract class is written in an italic font. This class contains one abstract method called calculatePay, it is written in a italic font. An abstract method has no implementation. Typically an abstract class contains one or more abstract method. The diagram also shows three subclasses that inherit behaviour and data attributes from the Employee class. These are concrete classes that can be instantiated; abstract classes cannot directly be instantiated. Think of abstract classes are providing some generic behaviour but also delegating some behaviour to a subclass. The subclass will have to provide the delegated behaviour or it will also have to be marked as abstract and hence will not be able to be instantiated.
Key point: When extending an abstract class the subclass must implement all of the abstract methods in order to be classified as a concrete class.
Returning to the diagram, each of the subclasses provides its own implementation of the calculatePay method. This means that each class provides an implementation of the abstract behaviour but each subclass does that in a slightly different way.
It is often assumed that all superclasses must be abstract. This is not so. Instances of a concrete superclass represent the 'normal' cases; instances of its subclasses represent special exceptions. E.g. Instances of SavingsProduct are 'normal' products; instances of TaxExemptSavingsProduct are also savings products - but ones which encapsulate special rules.
Key point: The bottom-level classes must be concrete, otherwise no instances will ever be created that exhibit the defined behaviour!!