An example of a class where overriding is needed is a RestartCounter class. A RestartCounter is just like a counter except that the Reset method always sets the internal value back to its initial value and does not use the TextBox to obtain the value to which the RestartCounter is reset.
The inheritance diagram for the RestartCounter class is shown below. This diagram implies that an RestartCounter object has the following methods:
Notice the difference between overloading and overriding. Overloaded methods have the same name but different argument lists (signatures). Overridden methods have the same name and the same arguments (signatures). In the JumpCounter class the Next method is overloaded because the two methods JumpCounter::Next(int) and Counter::Next() have different signatures. Thus, a JumpCounter object has both of the Next methods. However, a RestartCounter object has only one Reset method - the one defined in the RestartCounter class (RestartCounter::Reset()).
The definition of the RestartCounter class and its code is:
class RestartCounter : public Counter { private: int original; public: RestartCounter(int init=0); void Reset(); // overrides inherited method ~RestartCounter((); }; RestartCounter::RestartCounter(int init) : Counter(init) { original = init; } void RestartCounter::Reset() { value = original; } RestartCounter::~RestartCounter() {}To emphasize again the role of inheritance, the following code illustrates that a RestartCounter object has all of the (non-overidden) methods of its ancestors (Counter and DisplayableNumber):
TextBox display(Location(100,100), Shape(50,50)); RestatCounter restart(7); restart.Next(); // from Counter restart.ShowIn(display); // from DisplayableNumber restart.Show(); // from DisplayableNumber restart.Reset(); // from RestartCounter (overrides // DisplayableNumber::Reset()
The implementation of an overriding method may use the overridden method. In this sense the overriding method extends in some way the original, inherited method. An example of where this is useful is in the Cycler class. As the class was defined earlier, it inherits a Reset method from the DisplayableNumber class. However, this inherited method allows any number to be entered by the user - possibly one outside the range of the Cycler. If this occurred, the program could access this erroneous value (via the Value method). To prevent this problem from occurring a safer (more restricted) Reset method is needed in the Cycler class. To override and extend the inherited Reset method, the Cycler class would be redefined as follows:
class Cycler : public DisplayableNumber { private: int base; public: Cycler(int b, int init = 0); void Next(); void Reset(); // overrides and extends the Reset // method inherited from DisplayableNumber ~Cycler(); };and the Cycler::Reset method would be implemented as follows:
void Cycler::Reset() { DisplayableNumber::Reset(); // invoke overridden method value = value % base; }In this method the overriden base class method is itself invoked. To distinguish between the two Reset methods, the syntax "DisplayableNumber::Reset" is used in the Cycler's Reset method to name the Reset method in the base class (DisplayableNumber). Without this additional syntax to specify the base class name, it would be assumed that the Cycler's Reset method was making a recursive call on itself. This is clearly not what is desired here.