# Composition over Inheritance

Composition over Inheritance is a principle in object-oriented programming (OOP) that suggests that classes should achieve code reuse and polymorphic behavior by containing instances of other classes that implement the desired functionality, rather than inheriting from a base or parent class.

## 1. The Core Concept

*   **Inheritance ("Is-A"):** You design your types around what they *are*. (e.g., A `Car` is a `Vehicle`).
*   **Composition ("Has-A"):** You design your types around what they *do* or *have*. (e.g., A `Car` has an `Engine`).

The principle argues that Composition is generally more flexible and less brittle than Inheritance.

## 2. The Problems with Inheritance

While inheritance is powerful, overuse leads to several issues:

### The Fragile Base Class Problem
Changes to the parent class can inadvertently break child classes. The child class is tightly coupled to the implementation details of the parent.

### The Gorilla / Banana Problem
> "You wanted a banana but what you got was a gorilla holding the banana and the entire jungle." — Joe Armstrong

When you inherit from a class, you get *everything*—all its data and methods, even the ones you don't need.

### Hierarchy Explosion
Imagine a game with `Monster`. You have `FlyingMonster` and `SwimmingMonster`. What happens when you need a `FlyingSwimmingMonster`? You can't inherit from both (in many languages). You end up with a deep, messy tree.

## 3. The Solution: Composition

Instead of inheriting behavior, you compose it. You create small, focused classes (components) and combine them.

### Example: Inheritance (The Wrong Way)

```java
class Robot {
    void move() { ... }
    void clean() { ... }
}

class CleaningRobot extends Robot {
    // Inherits move and clean
}

class FightingRobot extends Robot {
    // Inherits move and clean... but wait, fighting robots don't clean!
    // Now you have a useless clean() method.
}
```

### Example: Composition (The Right Way)

```java
interface MovementBehavior {
    void move();
}

interface CleaningBehavior {
    void clean();
}

class Robot {
    private MovementBehavior mover;
    private CleaningBehavior cleaner;

    public Robot(MovementBehavior mover, CleaningBehavior cleaner) {
        this.mover = mover;
        this.cleaner = cleaner;
    }

    void performTasks() {
        if (mover != null) mover.move();
        if (cleaner != null) cleaner.clean();
    }
}

// Usage
Robot cleanerBot = new Robot(new Wheels(), new Vacuum());
Robot fighterBot = new Robot(new Legs(), null); // No cleaning behavior!
```

## 4. Benefits of Composition

1.  **Flexibility:** You can change behavior at runtime by swapping components (e.g., changing a `Engine` from `Gas` to `Electric`).
2.  **Loose Coupling:** Classes depend on interfaces, not concrete implementations.
3.  **Testability:** Easier to mock individual components.
4.  **Single Responsibility:** Each component does one thing well.

## 5. When to use Inheritance?

Inheritance isn't dead. Use it when:
*   There is a strict "Is-A" relationship.
*   You want to enforce a common interface (polymorphism) without code reuse (Interfaces/Abstract Classes).
*   The base class code is stable and unlikely to change.

## 6. Mixins

Mixins are a form of code reuse that sits somewhere between inheritance and composition. A Mixin is a class containing methods that can be used by other classes without needing to be the parent class of those other classes.

*   **Concept:** "Included" behavior. A class can "mix in" functionality from multiple sources.
*   **Language Support:** Supported natively in languages like Ruby, Python (via multiple inheritance), and TypeScript/JavaScript.

### Example (TypeScript)

```typescript
// A Mixin that adds flying capability
function Flyable<TBase extends new (...args: any[]) => {}>(Base: TBase) {
    return class extends Base {
        fly() {
            console.log("Flying high!");
        }
    };
}

// A Mixin that adds swimming capability
function Swimmable<TBase extends new (...args: any[]) => {}>(Base: TBase) {
    return class extends Base {
        swim() {
            console.log("Swimming deep!");
        }
    };
}

class Monster {}

// Compose a new class using Mixins
const FlyingSwimmingMonster = Swimmable(Flyable(Monster));

const monster = new FlyingSwimmingMonster();
monster.fly();
monster.swim();
```

[[programming/object-oriented-programming]]
[[programming/design-patterns]]
[[programming/software-design-principles]]