Difference between Inheritance and Composition in Java

1. Introduction

In Java, composition and inheritance are two programming techniques that model the relationship between two classes. Inheritance is used to express an "is-a" relationship, indicating that one class is a specialized version of another. Composition, on the other hand, describes a "has-a" relationship, indicating that one class contains an instance of another class as a part of its state.

2. Key Points

1. Inheritance extends a class using the extends keyword, creating a subclass that inherits methods and variables from the parent class.

2. Composition involves creating classes that contain instances of other classes within them.

3. Inheritance promotes code reusability but can lead to fragile code due to tight coupling.

4. Composition promotes code flexibility and reusability without the fragility of inheritance.

3. Differences

Inheritance Composition
Establishes an "is-a" relationship between the base (superclass) and derived (subclass) classes. Establishes a "has-a" relationship, where one class contains an instance of another to add functionality.
Achieved through the extends keyword in Java. Achieved by including an instance of another class as a field in the class.
Inheritance allows the subclass to inherit methods and fields from the superclass directly. Composition allows the containing class to call methods of the contained class, but the contained class's methods and fields are not inherited by the containing class.
Provides a way to reuse code, as the subclass can use or override the superclass methods and fields. Provides a way to reuse code by delegating tasks to the objects of other classes.
This can lead to tightly coupled code, especially if subclasses depend heavily on the superclass's implementation. Promotes loose coupling, making the system more modular and easier to change or extend.
Inheritance is static and defined at compile-time. Changing the inheritance hierarchy requires recompiling the code. Composition is dynamic and can be modified at runtime, allowing for more flexible system designs.
Java supports single inheritance, meaning a class can only extend one other class. A class can compose multiple other classes, allowing for more flexibility in design.

4. Example


// Example of Inheritance
class Vehicle {
    void start() {
        System.out.println("Vehicle started");
    }
}

class Car extends Vehicle {
    void openTrunk() {
        System.out.println("Trunk opened");
    }
}

// Example of Composition
class Engine {
    void start() {
        System.out.println("Engine started");
    }
}

class CarWithComposition {
    private Engine engine;

    CarWithComposition() {
        engine = new Engine();
    }

    void startCar() {
        engine.start();
        System.out.println("Car started");
    }
}

public class Main {
    public static void main(String[] args) {
        Car car = new Car();
        car.start(); // Inherited method
        car.openTrunk(); // Class method

        CarWithComposition compCar = new CarWithComposition();
        compCar.startCar(); // Composed method
    }
}

Output:

Vehicle started
Trunk opened
Engine started
Car started

Explanation:

1. The Car class inherits from Vehicle, demonstrating an "is-a" relationship. The car "is-a" vehicle.

2. The CarWithComposition class has an Engine, demonstrating a "has-a" relationship. The car "has-an" engine.

3. The Car class inherits the start method from Vehicle, while the CarWithComposition class can only start its Engine through its own startCar method.

4. CarWithComposition encapsulates the start behavior, and this encapsulation allows more control over the start process.

5. When to use?

- Use inheritance when classes are in a clear "is-a" relationship and you want to reuse code from the base class.

- Use composition to create more flexible designs that don't break easily with changes to the base class or when the "has-a" relationship makes more sense for the model.

Comments