Class Summary Notes¶
Abstract Base Classes¶
an abstract base class is a class where one, or more, of its methods are “= 0”, i.e. have no implementation
- it’s possible that an abstract base class could have some methods that are
not
= 0
- a base class is meant to have other classes inherit from it
- an
= 0
method is also known as a pure virtual method
for example:
class Stringable {
public:
virtual string to_str() const = 0;
virtual ~Stringable() { }
};
class Student :: public Stringable {
// ...
public:
// ...
string to_str() const {
return "<string representation of this object>";
}
}
abstract base classes they are used to specify what methods an object must saying how they must be implemented
they are an example of interface inheritance, i.e. you can only inherit the header (signature) of methods from an abstract base class (there is no body to inherit)
see below for how interface inheritance contrasts with implementation inheritance
you cannot create objects of an abstract base class type (because they have
unimplemented methods), but you can create pointers to objects of the
abstract base class type, e.g. you cannot create a Stringable
object, but
you can create a pointer of type Stringable*
that points to a Student
object
always remember to include a virtual destructor so that inheriting classes are able to implement their own destructors if they need to
it’s possible (and useful) for one class to inherit from more than one abstract base class; this is known as multiple inheritance
- however, we will not be using any multiple inheritance in this course
Implementation Inheritance¶
you can also inherit from classes that are not abstract base classes
i.e. you can inherit from a class that has an implemented method
this can sometimes be useful in practice, but multiple inheritance with classes that have implemented methods is more complicated than for abstract base classes
we will mostly avoid implementation inheritance in this course
Class Hierarchies and Class Diagrams¶
in big object-oriented programs, it is common to have multiple classes related to each other via inheritance
this is known as a class hierarchy, and is often represented using a class diagram where classes are in rectangles and arrows are used to indicate inheritance
designing good class hierarchies is surprisingly tricky, and requires careful thought (and experience)
Class Hierarchies¶
suppose you have a class called Circle
that represents circles, and a
class called Ellipse
that represents ellipses
should Circle
inherit from Ellipse
, or should Ellipse
inherit from
Circle
?
some programmers say Circle
should inherit from Ellipse
because,
mathematically, a circle is an ellipse, i.e. the set of circles is a subset of
the set of ellipses
but this can lead to serious problems!
if
Ellipse
has methodsset_height(h)
andset_width(w)
, then we can write code like this:Circle c(10); // a circle of radius 10 c.set_width(5); c.set_height(15); // ???: a circle's width and height can't be different
some programmers say Ellipse
should inherit from Circle
because a
Circle
stores one radius, and an Ellipse
stores two radii, and so
Ellipse
is extending Circle
by adding one more radius
but this can also lead to serious problems!
consider this function:
double area(Circle c) { return 3.14 * c.radius() * c.radius(); }
since an
Ellipse
inherits fromCircle
, we can write code like this:Ellipse e(5, 10); // an ellipse 5 wide, 10 high cout << area(c); // this can't return the correct area!
the
area
function only checks one radius, but to correctly calculate the area of anEllipse
you need two radii
so it seems that Circle
and Ellipse
have no good way to be related by
inheritance at all!
both ways of doing the inheritance can lead to serious problems