Professional C__ - Marc Gregoire [107]
Extending Classes
When you write a class definition in C++, you can tell the compiler that your class is inheriting from, or extending, an existing class. By doing so, your class will automatically contain the data members and methods of the original class, which is called the parent class or superclass. Extending an existing class gives your class (which is now called a derived class or a subclass) the ability to describe only the ways in which it is different from the parent class.
To extend a class in C++, you specify the class you are extending when you write the class definition. To show the syntax for inheritance, you use two classes called Super and Sub. Don’t worry — more interesting examples are coming later. To begin, consider the following definition for the Super class:
class Super
{
public:
Super();
void someMethod();
protected:
int mProtectedInt;
private:
int mPrivateInt;
};
If you wanted to build a new class, called Sub, which inherits from Super, you would tell the compiler that Sub derives from Super with the following syntax:
class Sub : public Super
{
public:
Sub();
void someOtherMethod();
};
Sub itself is a full-fledged class that just happens to share the characteristics of the Super class. Don’t worry about the word public for now — its meaning is explained later in this chapter. Figure 8-1 shows the simple relationship between Sub and Super. You can declare objects of type Sub just like any other object. You could even define a third class that subclasses Sub, forming a chain of classes, as shown in Figure 8-2.
FIGURE 8-1
FIGURE 8-2
Sub doesn’t have to be the only subclass of Super. Additional classes can also subclass Super, effectively becoming siblings to Sub, as shown in Figure 8-3.
FIGURE 8-3
A Client’s View of Inheritance
To a client, or another part of your code, an object of type Sub is also an object of type Super because Sub inherits from Super. This means that all the public methods and data members of Super and all the public methods and data members of Sub are available.
Code that uses the subclass does not need to know which class in your inheritance chain has defined a method in order to call it. For example, the following code calls two methods of a Sub object even though one of the methods was defined by the Super class:
Sub mySub;
mySub.someMethod();
mySub.someOtherMethod();
It is important to understand that inheritance works in only one direction. The Sub class has a very clearly defined relationship to the Super class, but the Super class, as written, doesn’t know anything about the Sub class. That means that objects of type Super do not support public methods and data members of Sub because Super is not a Sub.
The following code will not compile because the Super class does not contain a public method called someOtherMethod():
Super mySuper;
mySuper.someOtherMethod(); // BUG! Super doesn't have a someOtherMethod().
From the perspective of other code, an object belongs to its defined class as well as to any superclasses.
A pointer or reference to an object can refer to an object of the declared class or any of its subclasses. This tricky subject is explained in detail later in this chapter. The concept to understand at this point is that a pointer to a Super can actually be pointing to a Sub object. The same is true for a reference. The client can still access only the methods and data members that exist in Super, but through this mechanism, any code that operates on a Super can also operate on a Sub.
For example, the following code compiles and works just fine even though it initially appears that there is a type mismatch:
Super* superPointer = new Sub(); // Create sub, store it in super pointer.
However, you cannot call methods from the Sub class through the Super pointer. The following will not work:
superPointer->someOtherMethod();
This will be flagged as an error by the compiler, because, although the object is of type Sub and therefore does have someOtherMethod() defined,