An example of where base class redesign is needed occurs in developing an OctalCounter class. An OctalCounter object is just like a Counter object except that the OctalCounter object's value is displayed using octal number notation and not as a decimal value. For example, the decimal value "23" would be displayed in its octal representation as "27".
While most of the methods in the Counter and DisplayableNumber classes are exactly those needed to implement an OctalCounter, the Show method is inappropriate because it displays values in a decimal notation. The inherited Show method must be replaced (overriden) by a Show method that displays the value in octal notation.
However, overriding the show method leads to a dilemma regarding the sharing of data between the base and derived class. The Show method uses the textBox variable to display the DisplayableNumber's current value. To override the Show method in a derived class, the textBox variable must be placed in the protected region of the base class. This change, while workable, significantly enlarges the scope (i.e., weakes the protection) of the textBox variable. The base class no longer completely encapsulates the existance of the textBox variable. Therefore, both the base class and its derived classes are dependent on the following design decisions:
The cause of the problem is that the Show method performs two related, but seperable, actions:
Separating the two actions of the Show method leads to the following code:
class DisplayableNumber { private: TextBox* textBox; protected: int value; virtual char* Format(); // take value produce string to display public: DisplayableNumber(int initValue = 0); void ShowIn(TextBox& p); void Show(); void Reset(); ~DisplayableNumber(); }; char* DisplayableNumber::Format() { char* asString = new char[10]; sprintf(asString, "%10d", value); } void DisplayableNumber::Show() { if (textBox) textBox->SetText(Format()); }
Last Updated: March 26, 1996 / kafura@cs.vt.edu