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 = 0method 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 - Ellipsehas methods- set_height(h)and- set_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 - Ellipseinherits from- Circle, 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 - areafunction only checks one radius, but to correctly calculate the area of an- Ellipseyou 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