[ fromfile: inheritance-intro.xml id: abstractbaseclass ]
An abstract base class is used to encapsulate common features of concrete derived classes.
An abstract class cannot be instantiated.
A concrete class represents a particular kind of entity, something that really exists (i.e., can be instantiated).
At first, it might seem counterintuitive to define a class for an abstract idea that has no concrete representative. But classes are groupings of functions and data and are useful tools to enable certain kinds of organization and reuse. Categorizing things makes the world simpler and more manageable for humans and computers.
An abstract base class is a class that is impossible or inappropriate to instantiate.
Features of a class that tell the compiler to enforce this rule are
Having at least one pure virtual
function.
Having no public constructors.
Now look at an example of an abstract Shape
class that has pure virtual
functions.
The names of abstract classes are italicized in UML diagrams.
A pure virtual
function has the following declaration syntax:
virtual returnType
functionName(parameterList)=0;
Example 6.13. src/derivation/shape1/shapes.h
getName()
, area()
, and getDimensions()
are all pure virtual
functions.
Because they are defined to be pure virtual
, no function definition is required in the Shape
class.
Any concrete derived class must override and define all pure virtual base class functions for instantiation to be permitted.
In other words, any derived class that does not override and define all pure virtual base class functions is, itself, an abstract class.
Example 6.14. src/derivation/shape1/shapes.h
[ . . . . ] class Rectangle : public Shape { public: Rectangle(double h, double w) : m_Height(h), m_Width(w) {} double area(); QString getName(); QString getDimensions(); protected: double m_Height, m_Width; }; class Square : public Rectangle { public: Square(double h) : Rectangle(h,h) { } double area(); QString getName(); QString getDimensions(); }; class Circle : public Shape { public: Circle(double r) : m_Radius(r) {} double area(); QString getName(); QString getDimensions(); private: double m_Radius; };
Example 6.15. src/derivation/shape1/shapes.cpp
Example 6.16 provides some client code to exercise these classes.
Example 6.16. src/derivation/shape1/shape1.cpp
#include "shapes.h" #include <QString> #include <QDebug> void showNameAndArea(Shape* pshp) { qDebug() << pshp->getName() << " " << pshp->getDimensions() << " area= " << pshp->area(); } int main() { Shape shp; Rectangle rectangle(4.1, 5.2); Square square(5.1); Circle circle(6.1); qDebug() << "This program uses hierarchies for Shapes"; showNameAndArea(&rectangle); showNameAndArea(&circle); showNameAndArea(&square); return 0; }
In the global function showNameAndArea()
the base class pointer, pshp
, is successively given the addresses of objects of the three subclasses.
For each address assignment, pshp
polymorphically invokes the correct getName()
and area()
functions.
Example 6.17 shows the output of the program.
Example 6.17. src/derivation/shape1/shape.txt
This program uses hierarchies for Shapes RECTANGLE Height = 4.1 Width = 5.2 area = 21.32 CIRCLE Radius = 6.1 area = 116.899 SQUARE Height = 5.1 area = 26.01
Generated: 2012-03-02 | © 2012 Alan Ezust and Paul Ezust. |