It is good to design so that systems are extensible. This means that general
data and methods, common to all child classes are put in the parent class.
Specific data and operations go into the child class. Sometimes though while
a parent, say a Shape class, can specify the kind of task, e.g., draw,
it cannot specify the implementation as it varies from object to object.
E.g., drawing a circle is different from drawing a rectangle even though
"draw" as a task is clear.
+-------------+ | Shape | | void draw() | +-------------+ /\ /\ /__\ /__\ | | | | | | +---------+ +---------+ | Oval | | Polygon | +---------+ +---------+ /\ /\ /__\ /__\ | | | | | | +--------+ +-----------+ | Circle | | Rectangle | +--------+ +-----------+
Polymorphism -- the ability for objects of different classes related by
inheritance to respond differently (yet appropriately similar) to the same
member function call.
This is similar to overloading of functions, but the signatures are the same
and inheritance is implied. It is called overriding. This kind of call
is known as a polymorphic call.
Overloading -- two methods have different signatures.
Overriding -- two methods have the exact same signature.
Polymorphism is implemented using virtual functions.
Virtual functions
A function can be defined as virtual. A virtual function is how polymorphism
is implemented. In general, being virtual means to use the child class method
whenever possible. This only applies when the object is being viewed as
being of the type of its parent. A virtual function is used by a child
class when no function is defined. E.g., consider the list of Fruit example:
     
Fruit* ptr;
     
ptr = new Apple("carter");
The pointer to the Apple object is implicitly cast to be a Fruit pointer.
Unless a virtual function is used with ptr, it is treated as a Fruit.
For example, if the following code is used
     
ptr->print();
if the print routine is virtual, then the Apple's print is used. If the print
is not virtual, the Fruit's print is used.
Abstract/Concrete classes
When we define a class, we often want objects of that class, e.g., Rational. This is a concrete class.
Sometimes we don't want to instantiate objects of vague types.
We want organization of our class hierarchy, but no objects. For example,
in the shape hierarchy example, a shape is too vague to instantiate a shape
object. If "draw" were a function, how would we draw it?
Pure Virtual functions
This is when an abstract class is appropriate. Objects cannot be instantiated
of an abstract class. A class is abstract if it has at least one pure virtual
function. Pure virtual functions have "= 0" and no body.
E.g., Shape has pure virtual draw:
     
virtual void draw() const = 0;
If you inherit a pure virtual function, you MUST implement it. Any class that inherits a pure virtual function and doesn't provide an implementation is also abstract, i.e., the class inherits the function as pure virtual and so on down the hierarchy until it gets implemented.