Unit 4 · Association, Aggregation and Composition

4.3Composition

Composition is the strongest has-a relationship. The whole is made of its parts and is responsible for them: it creates them, uses them and lets them die with it.

Composition is a stronger form of "has-a": the whole owns its parts, and the parts cannot exist without the whole. When the whole is destroyed, its parts are destroyed too. It is a "part-of" relationship.

Examples: a House has Rooms; a Book has Chapters; a Car has an Engine; an Order has OrderLines.

Java
class Engine {
    private int power;
    Engine(int power) { this.power = power; }
    void start() { System.out.println("Engine " + power + "hp started"); }
}

class Car {
    private final Engine engine;           // part owned by the car

    Car(int power) {
        this.engine = new Engine(power);   // part CREATED INSIDE the whole
    }
    void drive() { engine.start(); System.out.println("Car moving"); }
}

Car c = new Car(150);
c.drive();
// no way for outside code to hold or reuse that Engine; when c is
// collected, its Engine goes with it

Key code pattern: the part is created inside the whole's constructor and not shared with the outside.

CarEngine11ownsparts are created inside and are not shared
Composition (filled diamond at the whole): the Engine is created inside the Car and lives and dies with it

Reading the Car example

Do not leak the parts

Composition only works if the whole keeps its parts to itself. If a class creates a part and then hands out a reference to it, outside code can hold on to the part, change it or share it, and the "owned" relationship is broken:

Java
class Order {
    private final List<OrderLine> lines = new ArrayList<>();

    void addLine(String product, int qty, double price) {
        lines.add(new OrderLine(product, qty, price));   // created inside
    }

    List<OrderLine> getLines() {
        return Collections.unmodifiableList(lines);      // read-only view
    }
}

The order creates its own lines from plain values, and it only returns a read-only view of the list, so nobody else can add or remove lines.

Composition over inheritance

A famous design rule says: prefer composition to inheritance. Inheritance ties the subclass tightly to its parent, because a change in the parent affects every subclass, and a class can only extend one parent. Composition is more flexible: a Car can have an Engine, a GPS and a Radio, and each part can be designed, tested and replaced on its own. Use inheritance only for a real is-a relationship, and use composition for everything that is a part of something else.

QuestionInheritanceComposition
Relationshipis-a (a Car is a Vehicle)has-a / part-of (a Car has an Engine)
How it is writtenclass Car extends Vehicleprivate final Engine engine = new Engine(...)
Number allowedOne parent classAs many parts as needed
FlexibilityFixed when the code is compiledParts can be designed and changed separately

Remember

  • Composition: the whole creates and owns its parts, and they die with it.
  • Create the parts inside the whole, keep them private, and do not hand them out.
  • UML: a filled diamond at the whole.