When people say “favor composition over inheritance” that is short for “favor composition over class inheritance” (the original quote from “Design Patterns” by the Gang of Four) because class inheritance has many flaws and causes many problems. Often people leave off the word class when they talk about class inheritance, which makes it sound like all inheritance is bad — but it’s not.
There are actually several different kinds of inheritance, and only class inheritance is deeply flawed. The rest are OK:
Class inheritance: Rather than inheriting from other objects, classes inherit from classes, and create parent/child object taxonomies as a side-effect. Those taxonomies are virtually impossible to get right from the beginning for all new use cases, and widespread use of a base class leads to the fragile base class problem. In fact, there are many well known problems with class inheritance with well known names:
- The tight coupling problem (class inheritance is the tightest coupling available in oo design), which leads to the next one…
- The fragile base class problem
- Inflexible hierarchy problem (eventually, all evolving hierarchies are wrong for new uses)
- The duplication by necessity problem (due to inflexible hierarchies, new use cases are often shoe-horned in by duplicating, rather than adapting existing code)
- The Gorilla/banana problem (What you wanted was a banana, but what you got was a gorilla holding the banana, and the entire jungle)
I discuss some of the issues in more depth in my talk, “Classical Inheritance is Obsolete: How to Think in Prototypal OO”:
The solution to all of these problems is to favor object composition over class inheritance.
Summed up nicely here: