One of the main benefits of OO-style is reuse of code. Reuse is achieved through subtype polymorphism, i.e., the same piece of code can operate on objects of different type, as long as: (a) their types are derived from a common base class (b) the code assumes only fields and operations supported by the base class. (As we will discuss later, subtype polymorphism is based on the fact that all subclasses of a base class support the operations declared in the base class, although their implementations may be differ across the subclasses. This notion of same-name-but-different-function is nothing by function overloading that we have discussed before. One difference in this context is that the overloading is resolved at runtime, rather than at compile time. This observation leads us to the following conclusion regarding reuse enabled by subtype polymorphism: just as overloading enables reuse of client code, subtype polymorphism enables reuse of client code.) The following example embodies the essence of reuse enabled in OO-languages. Consider a graphical editor program. Consider the implementation of one of the functions to be supported by this program, namely, that of redrawing the screen. Conceptually, this is a very simple operation: we simply need to sequence through all of the objects on the screen and redraw them. This conceptual description can be realized in an OO-language as follows. First, we define a base class called DrawableOblect that supports operations that are common to all objects that can be drawn on the screen. These operations may include draw() and erase(). Since the actual implementation of these operations will differ across different kinds of graphical objects, we cannot provide an implementation of this method in the base class. Thus, DrawableObject just defines an interface: no implementations for the methods are provided. The subclasses of this class can provide the implementations of these methods. We use the terms "abstract method", "deferred method" and "pure virtual function" to refer to such methods whose definition is not provided in a base class. We also use the term "abstract" class to refer to classes that have one or more abstract methods. (The reason for this name is that we cannot create objects of with such a type, since such an object will not provide implementations of some methods.) A class that consists of only abstract methods (and no data members) is called an interface class. The hierarchy of DrawableObject may look as follows: DrawableObject / \ / \ / / GeometricShapes BitMaps / \ /\ / \ / \ ClosedFigures OpenFigures / \ / \ ... JPEG GIF / \ Polygon Ellipse / \ | / \ Circle Rectangle Triangle | | Square The subclasses support the draw() and erase() operation supported by the base class. In addition, they may support additional operations: for instance, the ClosedFigures class may support operations such as center(), area(), etc. Given this setting, we can implement the redraw routine using the following code fragment: void redraw(DrawableObject* objList[], int size) { for (int i = 0; i < size; i++) objList[i]->draw(); } Note that due to the nature of dynamic dispatching of virtual functions, objList[i].draw will call the appropriate draw method: for a square object, Square::draw will be called, while for a circle object, Circle:draw will be called. Most important, the above code need not be changed even if we modify the inheritance hierarchy by adding new subtypes. For instance, we may add a new kind of object, say a Hexagon. We need only provide the implementation of draw() and r draw() for that class. The above redraw() function need not be changed at all! Without OO-languages, this sort of reuse is difficult to achieve. For instance, if we were to implement the graphical editor in C, we may use the following code to implement redraw: void redraw(DrawableObject *objList[], int size) { for (int i = 0; i < size; i++) { switch (objList[i]->type) { case SQUARE: square_draw((struct Square *)objList[i]); break; case CIRCLE: circle_draw((struct Circle *)objList[i]); break; ........ default: .... } } The key difference in this code is that no reuse is possible across different types such as Circle and Square: we have to explicitly check the type of the object at runtime, and explicitly invoke the operation appropriate for that type. A consequence of this is that the code for redraw needs to be changed any time we want to add a new type of DrawableObject, such as a Hexagon.