ReviseAlgo Logo

Advanced OOP

Composition vs Inheritance

Choosing the right approach for code reuse

Interview: Design decisions — tests understanding of coupling, flexibility, and when to prefer composition over inheritance

Last Updated: June 12, 2026 6 min read

"Prefer composition over inheritance" is one of the most important design principles in OOP. Composition means building objects from other objects ("has-a" relationship), while inheritance means extending a parent class ("is-a" relationship). Composition provides more flexibility and less coupling, making code easier to change and test.

When to Use Each

  • Inheritance (is-a): Dog IS-A Animal, Square IS-A Shape
  • Composition (has-a): Car HAS-A Engine, User HAS-A Profile
  • Aggregation: Weak "has-a" — parts can exist independently
  • When in doubt, prefer composition — it's more flexible

Why Composition Wins

  • Flexibility: Swap components at runtime
  • Testability: Mock individual components easily
  • Loose coupling: Changes to one component don't break others
  • No fragile base class: Avoid inheritance hierarchy issues

Common Pitfall

Deep inheritance hierarchies (>2-3 levels) are a code smell. If you're inheriting to reuse code (not to model "is-a"), switch to composition.

Use Cases

Building complex objects from interchangeable components

Strategy pattern: swappable algorithms (payment, sorting, compression)

Service layer: composing services from pluggable components

Game entities: composing behavior from independent component systems

Testing: replacing real components with mocks/stubs

Common Mistakes

Using inheritance for code reuse when composition would be more flexible

Deep inheritance hierarchies (>2-3 levels) that are hard to understand

Not injecting dependencies (hardcoding component creation inside classes)

Over-composing: sometimes simple inheritance is the right choice

Forgetting to define clear interfaces (protocols) between composed components