Composition over Inheritance advocates using object composition rather than class inheritance to achieve code reuse and polymorphism.

Core Concept

Favor “has-a” relationships (composition) over “is-a” relationships (inheritance) when designing object-oriented systems.

Why Composition is Preferred

Problems with Inheritance

  • Tight Coupling: Child classes depend on parent implementation details
  • Fragile Base Class: Changes to parent can break child classes
  • Limited Flexibility: Single inheritance languages restrict options
  • Forced Relationships: Not all hierarchies map well to “is-a” relationships

Benefits of Composition

  • Loose Coupling: Objects depend on interfaces, not implementations
  • Flexibility: Combine behaviors from multiple sources
  • Testability: Easier to mock and test composed objects
  • Runtime Behavior: Can change behavior dynamically

Example

Inheritance Approach (Rigid)

// Inflexible hierarchy
public abstract class Bird
{
    public abstract void Move();
}
 
public class FlyingBird : Bird
{
    public override void Move() => Fly();
}
 
public class Penguin : Bird
{
    public override void Move() => Swim(); // Awkward - penguins don't fly!
}

Composition Approach (Flexible)

// Flexible composition
public interface IMovementBehavior
{
    void Move();
}
 
public class FlyingBehavior : IMovementBehavior
{
    public void Move() => Console.WriteLine("Flying");
}
 
public class SwimmingBehavior : IMovementBehavior
{
    public void Move() => Console.WriteLine("Swimming");
}
 
public class Bird
{
    private readonly IMovementBehavior _movement;
 
    public Bird(IMovementBehavior movement)
    {
        _movement = movement;
    }
 
    public void Move() => _movement.Move();
}
 
// Usage
var eagle = new Bird(new FlyingBehavior());
var penguin = new Bird(new SwimmingBehavior());

When to Use Inheritance

Inheritance is appropriate when:

  • True “is-a” relationship exists
  • Liskov Substitution Principle can be maintained
  • You’re extending framework classes designed for inheritance
  • The hierarchy is shallow and unlikely to change

Resources