Short answer
Inheritance creates a tight, compile-time 'is-a' coupling where the subclass depends on the superclass's implementation details, so a superclass change can silently break subclasses (the fragile base class problem).
Explanation
Composition delegates to a contained object via 'has-a', which is more flexible, swappable at runtime, and keeps encapsulation intact. The rule exists because deep inheritance hierarchies become rigid and hard to evolve; inheritance is appropriate only for genuine, stable is-a relationships, and even then often behind an interface.
Common mistakes
- Using inheritance just to reuse code when there is no real is-a relationship.
- Not mentioning that inheritance breaks encapsulation of the parent.