Composition and Aggregation in Java

Composition and Aggregation in Java

In Java, composition and aggregation define relationships between classes, allowing us to model real-world scenarios by linking objects within a program. These relationships enable classes to work together without being hierarchically dependent on each other, unlike inheritance. Here, we’ll explain these relationships with examples and scenarios for clear understanding. You can visit the detailed tutorial here.

1. Composition in Java

Composition in Java

Composition represents a strong relationship between two classes. If an object (child) is a part of another object (parent), and cannot exist independently, this relationship is known as composition. The lifecycle of the contained (child) object is bound to the lifecycle of the container (parent) object. In simpler terms, if the parent object is destroyed, the child object is also destroyed.

Example: Car and Engine

Let’s consider a Car class that has an Engine. Here, a car cannot function without an engine, and if the car is destroyed, the engine is as well. This scenario makes Engine a part of Car, demonstrating a “has-a” relationship.

Code Example:

// Engine class representing the part of a Car
class Engine {
    private String type;

    public Engine(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }

    public void start() {
        System.out.println("Engine of type " + type + " is starting.");
    }
}

// Car class that uses Composition
class Car {
    private Engine engine;  // Car "has-an" Engine

    public Car(String engineType) {
        this.engine = new Engine(engineType);  // Composition: Engine is created and owned by Car
    }

    public void startCar() {
        System.out.println("Car is starting.");
        engine.start();  // Car depends on Engine's functionality
    }

    public void showDetails() {
        System.out.println("Car with engine type: " + engine.getType());
    }
}

public class CompositionDemo {
    public static void main(String[] args) {
        Car car = new Car("V8");
        car.startCar();
        car.showDetails();
        // Output:
        // Car is starting.
        // Engine of type V8 is starting.
        // Car with engine type: V8
    }
}

Explanation:

  • In this example, Car contains an Engine object. The Engine is a part of Car, and it is created inside the Car constructor. This means that without Car, there is no independent Engine.
  • This relationship is composition because the Engine is entirely dependent on the existence of Car.

2. Aggregation in Java

Aggregation in Java

Aggregation represents a weaker relationship than composition. In aggregation, the contained (child) object can exist independently of the container (parent) object. In this case, the objects have their own lifecycles, and the destruction of one does not affect the existence of the other.

Example: House and Person

Imagine a scenario where a House contains a list of Person objects as its residents. Even if the House object is destroyed, the Person objects (people) still exist. This relationship reflects aggregation, as House aggregates Person objects, but they are not exclusively dependent on each other.

Code Example:

import java.util.ArrayList;
import java.util.List;

// Person class representing individual residents
class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

// House class using Aggregation
class House {
    private List<Person> residents;  // House "has" residents

    public House() {
        this.residents = new ArrayList<>();
    }

    public void addResident(Person person) {
        residents.add(person);  // Aggregation: House contains references to Person objects
    }

    public void showResidents() {
        System.out.println("House residents:");
        for (Person person : residents) {
            System.out.println(person.getName());
        }
    }
}

public class AggregationDemo {
    public static void main(String[] args) {
        // Creating Person objects independently
        Person person1 = new Person("Alice");
        Person person2 = new Person("Bob");

        // Creating House and adding residents
        House house = new House();
        house.addResident(person1);
        house.addResident(person2);

        house.showResidents();
        // Output:
        // House residents:
        // Alice
        // Bob
    }
}

Explanation:

  • The House class has a list of Person objects, but these Person instances are created independently and are not owned by the House.
  • If House is destroyed, the Person objects (people) still exist. This represents an aggregation relationship, where House and Person objects are loosely coupled and can exist independently.

Comparison of Composition and Aggregation

AspectCompositionAggregation
RelationshipStrong (“part-of”)Weak (“has-a”)
Lifetime DependencyDependent: child cannot exist without parentIndependent: child can exist without parent
ExampleCar and EngineHouse and Person
ImplementationContained object created within the parent classContained object passed from outside

When to Use Composition vs. Aggregation

  • Use composition when the contained object is a part of the parent object and cannot exist independently. Examples: Car and Engine, Body and Heart.
  • Use aggregation when the contained object can exist independently of the parent object. Examples: House and Person, Library and Book.

Composition and aggregation are essential in creating flexible and reusable class structures in object-oriented programming, allowing for modular designs that can represent complex relationships.

Visit the detailed presentation here.

14 thoughts on “Composition and Aggregation in Java

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this:
Verified by MonsterInsights