.NETMedium
Why favour composition over inheritance?
Inheritance creates a permanent is-a relationship that's hard to change. Composition is has-a — pluggable and reversible.
The inheritance trap:
public class Bird { public virtual void Fly() {} }
public class Penguin : Bird { /* ??? — Penguins don't fly */ }
You end up overriding Fly to throw NotSupportedException — a Liskov Substitution violation.
Composition fixes it:
public interface ICanFly { void Fly(); }
public interface ICanSwim { void Swim(); }
public class Eagle : ICanFly { public void Fly() {} }
public class Penguin : ICanSwim { public void Swim() {} }
public class Duck : ICanFly, ICanSwim { /* both */ }
Practical signs you should switch to composition:
- Three+ levels of inheritance — almost always a refactor candidate
- A subclass throws
NotImplementedException - You need to combine behaviours that the inheritance tree forces into a single chain
When inheritance still works: closed domains with genuine is-a relationships (Shape → Circle, Rectangle), or framework template methods (ASP.NET's ControllerBase). Two levels max.
Rule of thumb: if a base class has more than three abstract methods or more than 30 lines, it's secretly three classes trying to escape.