In this section, we discuss several polymorphism examples. With polymorphism, one function can cause different actions to occur, depending on the type of the object on which the function is invoked. This gives the programmer tremendous expressive capability. If class Rectangle is derived from class Quadrilateral, then a Rectangle object is a more specific version of a Quadrilateral object. Therefore, any operation (such as calculating the perimeter or the area) that can be performed on an object of class Quadrilateral also can be performed on an object of class Rectangle. Such operations also can be performed on other kinds of Quadrilaterals, such as Squares, Parallelograms and TRapezoids. The polymorphism occurs when a program invokes a virtual function through a base-class (i.e., Quadrilateral) pointer or referenceC++ dynamically (i.e., at execution time) chooses the correct function for the class from which the object was instantiated. You will see a code example that illustrates this process in Section 13.3.
As another example, suppose that we design a video game that manipulates objects of many different types, including objects of classes Martian, Venutian, Plutonian, SpaceShip and LaserBeam. Imagine that each of these classes inherits from the common base class SpaceObject, which contains member function draw. Each derived class implements this function in a manner appropriate for that class. A screen-manager program maintains a container (e.g., a vector) that holds SpaceObject pointers to objects of the various classes. To refresh the screen, the screen manager periodically sends each object the same messagenamely, draw. Each type of object responds in a unique way. For example, a Martian object might draw itself in red with the appropriate number of antennae. A SpaceShip object might draw itself as a silver flying saucer. A LaserBeam object might draw itself as a bright red beam across the screen. Again, the same message (in this case, draw) sent to a variety of objects has "many forms" of results.
A polymorphic screen manager facilitates adding new classes to a system with minimal modifications to its code. Suppose that we want to add objects of class Mercurian to our video game. To do so, we must build a class Mercurian that inherits from SpaceObject, but provides its own definition of member function draw. Then, when pointers to objects of class Mercurian appear in the container, the programmer does not need to modify the code for the screen manager. The screen manager invokes member function draw on every object in the container, regardless of the object's type, so the new Mercurian objects simply "plug right in." Thus, without modifying the system (other than to build and include the classes themselves), programmers can use polymorphism to accommodate additional classes, including ones that were not even envisioned when the system was created.
Software Engineering Observation 13.1
With virtual functions and polymorphism, you can deal in generalities and let the executiontime environment concern itself with the specifics. You can direct a variety of objects to behave in manners appropriate to those objects without even knowing their types (as long as those objects belong to the same inheritance hierarchy and are being accessed off a common base-class pointer).
Software Engineering Observation 13.2
Polymorphism promotes extensibility: Software written to invoke polymorphic behavior is written independently of the types of the objects to which messages are sent. Thus, new types of objects that can respond to existing messages can be incorporated into such a system without modifying the base system. Only client code that instantiates new objects must be modified to accommodate new types.