Subclassing and inheritance Some software vendors who say they use "objects" really mean that they provide libraries of object classes that can be used by simple instantiation as described in the previous section. But one of the primary benefits of objects involves the ability to extend and modify them: that is, to derive new kinds of objects from the standard objects available in the system, thereby creating new capabilities without having to start from scratch. Because characteristics shared by different classes are factored into shared base classes, one of the benefits of classes is code reuse through inheritance. Each class that derives from the base class inherits the parent's structure and behavior. Derived classes represent increasingly specialized entities founded on more abstract or general base classes. The ability to derive new classes from existing classes makes it possible to extend the capabilities of any part of Taligent's system software. If a CommonPoint class does exactly what an application requires for a particular purpose, the programmer can use it as is. If it does some but not all of what's needed, the programmer can derive a new class from the existing one and add new data structures and actions to extend its capabilities. For example, suppose you want to create a scrolling window. You can derive a new class called TScrollingWindow from the TWindow class, a process called subclassing. Figure 9 shows how this works. The new TScrollingWindow class inherits all the characteristics of TWindow. This means you start with (reuse) all the same data members and member functions and just add the new ones you need or replace the ones whose behavior you want to change. Inheritance relationships like this allow many different classes to share common characteristics. Two new data members, scrollX and scrollY, represent the horizontal and vertical scroll positions, which indicate what part of the content should be drawn inside the window. A new member function called DrawScrollbars draws the scroll bars, including the position of each scroll bar's "thumb" (the small box that moves up and down or left and right inside a scroll bar), which depends on the values of scrollX and scrollY. Finally, you need to replace the original TWindow DrawSelf member function with a new DrawSelf function that draws a scrolling window. The new DrawSelf function calls DrawFrame as before to draw the basic window, then calls the new DrawScrollbars member function to add the scroll bars, then calls the original DrawContents, but with slightly different arguments. The new arguments reflect both the reduced content area due to making room for the scroll bars and the shift in the contents indicated by the current values of scrollX and scrollY. In the programming language C++, the class from which a new class is derived by subclassing is called a base class, and the new class derived from a base class is called a derived class. Overriding Because TScrollingWindow inherits all the characteristics of the TWindow class, a program that uses TScrollingWindow ends up using the TWindow definitions of inherited functions such as Resize. When a program calls the DrawSelf function for a TScrollingWindow object, however, it doesn't use the original TWindow's DrawSelf function; instead, it overrides the original function: that is, it skips over the original and uses the new function definition provided by TScrollingWindow. Figure 10 illustrates this process. In C++, a function that can be overridden as shown in Figure 10 is called a virtual function, because it can (but need not) be replaced. If a base class provides no default implementation for a function, it is called a pure virtual function, because it's really just a "stub" or placeholder that can't be used as is and must therefore be overridden with an implementation provided by the programmer. Polymorphism Different kinds of windows that have different drawing requirements can each implement their own DrawSelf functions as shown in Figure 10. Thus, to draw any window object derived from the TWindow class, no matter what special drawing requirements it may have, you simply call its DrawSelf function. This ability to hide different implementations behind the same name, called polymorphism, greatly simplifies communication among objects. You can use the same name with many different kinds of objects to trigger the same effect without having to deal with the underlying mechanisms, which may be quite different. Polymorphism allows programmers to create their own custom versions of objects that plug back into the system and work in place of the originals. Multiple inheritance Suppose you want to derive a new class from the TScrollingWindow class. Objects of this new class, called TScrollingDrawingWindow, track mouse movements within the window whenever the mouse button is down. Suppose also that you have another class available, called MMouseTracker, that provides these mouse-tracking capabilities within a given area on screen but doesn't provide any of the capabilities provided by TScrollingWindow. Figure 11 shows how OOP addresses this kind of situation, which requires a form of inheritance called multiple inheritance. TScrollingDrawingWindow inherits characteristics of TScrollingWindow, which in turn inherits characteristics of TWindow. These three classes represent the main branch of the inheritance hierarchy for TScrollingDrawingWindow. But TScrollingDrawingWindow also "mixes in" the characteristics of the class MMouseTracker with the characteristics it inherits from TScrollingWindow, thus providing its own hybrid capabilities. Classes such as MMouseTracker that are designed for this purpose are called mixin classes. TScrollingDrawingWindow uses the capabilities inherited from MMouseTracker to keep track of the location of the mouse and overrides the DrawContents member function inherited from TScrollingWindow (which was in turn inherited from TWindow) to draw lines when the mouse button is down. TScrollingDrawingWindow inherits all the other scrolling and drawing capabilities of TScrollingWindow without changing them. NOTE Although Figure 11 follows the Taligent convention of beginning the names of mixin classes with "M," the example is highly simplified and doesn't reflect the way mouse tracking is actually handled in the CommonPoint system.