Inheritance is a troublesome facility; although it is undoubtedly powerful, it can cause a great many problems. To steer clear of these, it is important to understand what it is about inheritance that makes it so easy to go wrong. We have already discussed simple misuse, caused by the failure to understand that inheritance defines an “is a” relationship—if your derived class cannot be substituted for its base class, you will run into difficulties. But even when this design rule has not been broken, inheritance is still potentially dangerous. The fundamental problem with inheritance is that it tends to require the derived class to have an exceptionally close relationship with the base class.
In the autocompletion example above, we needed to know more than is
healthy about the way that the
works. First of all, we needed a pretty detailed understanding simply
to determine which methods to override. To implement these overrides
correctly, we also needed considerable lateral knowledge of the inner
workings of the control, to anticipate issues such as the deletion
problem. Inheritance requires knowledge of how the base class works
both in breadth and in depth.
This tight coupling between the derived and base classes introduces
another problem. If the base class evolves over time, it could easily
break classes that derive from it. In the
AutoTextBox class, we elected to autocomplete the
control’s text in our override of
OnTextChanged and not in