What is the difference between composition and inheritance, and why prefer composition?
Quick Answer
Inheritance models “is-a” — a subclass gets the base class's members automatically. Composition models “has-a” — a class holds instances of other classes and delegates work to them. Prefer composition because it is more flexible (swap parts at run time), avoids the fragile-base-class problem, and keeps class hierarchies shallow.
Inheritance is an “is-a” relationship where a subclass automatically gets everything from the base class. Composition is “has-a” — a class holds other objects and delegates to them. I prefer composition because inheritance couples the subclass to the base class's internals, so a base change can break subclasses — the fragile base class problem — and you're stuck with one base class chosen at compile time. With composition and interfaces I can swap the parts, mock them in tests, and keep the hierarchy flat. I still use inheritance for real, stable is-a relationships and framework base classes like Controller.
Problems with deep inheritance:
- Fragile base class — a change in the base can silently break every subclass.
- Tight coupling — a subclass depends on the base's implementation details.
- Rigidity — you can only inherit from one class; behaviour is fixed at compile time.
- Wrong hierarchies — forcing an “is-a” where it's really “has-a” (a
Stackis not really aList).
Composition + interfaces gives you the same reuse with looser coupling: a Car has an IEngine, and you can inject a PetrolEngine or an ElectricEngine. This is exactly what dependency injection encourages. Use inheritance for genuine, stable “is-a” relationships and shared framework base classes (Controller, Stream).