Skip to content

Composition over Inheritance

Instead of inheriting from a class, you include it as a member inside another class.

Inheritance = "is-a" relationship. Composition = "has-a" relationship.

Think: A Car IS-A Vehicle (Inheritance). A Car HAS-A Engine (Composition).

Wrong — Inheritance (Car IS-A Engine?)

cpp
class Car : public Engine { // Car IS-A Engine? doesn't make sense!
public:
    void drive() { start(); /* ... */ stop(); }
};

Correct — Composition (Car HAS-A Engine)

cpp
class Car {
    Engine engine; // Engine is a MEMBER of Car
public:
    void drive() {
        engine.start();
        cout << "Car is driving" << endl;
        engine.stop();
    }
};

Why Composition? — Problem with Inheritance

cpp
class Vehicle { public: void fuelUp() { /* ... */ } };
class PetrolCar : public Vehicle {};   // works
class ElectricCar : public Vehicle {}; // Electric car doesn't need fuel! breaks

Fix with Composition

cpp
class PetrolCar {
    FuelEngine engine; // has fuel engine only
public:
    void refuel() { engine.fuelUp(); }
};

class ElectricCar {
    ElectricEngine engine; // has electric engine only
public:
    void recharge() { engine.charge(); }
};

Composition vs Inheritance

InheritanceComposition
Relationshipis-ahas-a
CouplingTightLoose
FlexibilityLess flexibleMore flexible
Code reuseVia parent classVia member objects
Change impactParent change affects childChanges are isolated
When to useTrue is-a relationshipHas-a relationship

When to Use Inheritance

  • Dog IS-A Animal, Circle IS-A Shape, Car IS-A Vehicle

When to Use Composition

  • Car HAS-A Engine, Smartphone HAS-A Camera, School HAS-A Classroom, Library HAS-A Book

One-liner: "Composition over inheritance means preferring has-a relationships over is-a relationships, leading to loosely coupled, more flexible, and maintainable code."