Inheritance vs. Composition

About

In object-oriented programming, Inheritance and Composition are two fundamental techniques used to achieve code reuse and build relationships between classes. Though they aim for similar goals, they approach the problem differently and each has its own advantages and trade-offs.

What is Inheritance ?

Inheritance is a mechanism where a class (subclass or child) derives from another class (superclass or parent), inheriting its fields and methods.

  • Defines an "is-a" relationship.

  • Promotes code reuse by allowing subclasses to inherit behaviour.

  • Supports method overriding for polymorphism.

class Animal {
    void eat() {
        System.out.println("This animal eats food.");
    }
}

class Dog extends Animal {
    void bark() {
        System.out.println("The dog barks.");
    }
}

Usage

Dog d = new Dog();
d.eat();   // inherited from Animal
d.bark();  // defined in Dog

What is Composition?

Composition is a design technique in which a class is composed of one or more objects of other classes, allowing you to build complex types by combining simpler ones.

  • Defines a "has-a" relationship.

  • Offers greater flexibility and modularity.

  • Behavior is achieved by delegating tasks to internal objects.

class Engine {
    void start() {
        System.out.println("Engine starts");
    }
}

class Car {
    private Engine engine = new Engine();

    void startCar() {
        engine.start();  // delegation
        System.out.println("Car is running");
    }
}

Usage

Car car = new Car();
car.startCar();

Comparison

Feature
Inheritance
Composition

Relationship Type

"is-a"

"has-a"

Coupling

Tightly coupled (inherits implementation)

Loosely coupled (uses delegation)

Flexibility

Less flexible; tightly bound hierarchy

More flexible; can switch components

Code Reuse

Achieved through superclass

Achieved through composed objects

Method Overriding

Supports polymorphism

Doesn’t support overriding, but can delegate

Runtime Changes

Difficult

Easier to modify components

Hierarchy Depth

Can become deep and complex

Flatter and easier to manage

Example

Dog is-a Animal

Car has-a Engine

When to Use Inheritance & Composition ?

Use inheritance when:

  • The subclass is a specialized version of the superclass.

  • There is a clear is-a relationship.

  • We want to leverage polymorphism for method overriding.

  • The base class provides stable and reusable behavior.

Use composition when:

  • We need flexibility and maintainability.

  • We want to change behavior at runtime.

  • We want to reuse functionality without forming a strict hierarchy.

  • We want to avoid the problems of deep inheritance trees.

Last updated