I have a set of classes that are all dealing with some related tasks. These tasks do have different inputs and outputs. This causes it to become impossible to have the tasks done via shared code without having this code be a pile of if-else statements handling all the different cases.
Now someone refactored this code to use inheritance – there now is an abstract base class that holds methods for each of which it is used by some of the deriving classes, for some of which they get overridden or nullified and some of which are always called though not always applicable for the deriving class. Furthermore the inheritance is not used for polymorphism at all, just code reuse.
I cringed a bit when I noticed this refactoring was done and that it happily got through code review. The codebase I am working with has existed for quite a while and is full of these kind of things, and most people don’t understand the issues. I’m thus looking for a good overview of why inheritance should not be abused like this, esp including all the problems it causes.
1
The keyword (or phrase) to search for here is composition over inheritance. It’s a popular design guideline and you can find a general introduction at wikipedia.
Additionally, there is a community question here which provides you with a huge number of arguments on when to prefer CoI. As indicated by several (and highly valued) answers, the basic guideline for deciding between composition and inheritance is the Liskov substitution principle, which should be adhered to when using inheritance.
7