Class Relationships

Composition

A strong form of association where the part cannot exist without the whole. When the whole is destroyed, all its parts are destroyed too.

10 min readEssential

1What is Composition?

Real-World Analogy
Human and Heart

A human HAS a heart. The heart cannot exist independently - when the human dies, the heart is also gone. Heart is part of human. This is composition - strong ownership with shared lifecycle.

House and Rooms

A house HAS rooms. When you demolish the house, the rooms are destroyed too. The rooms cannot be transferred to another house - they are intrinsically part of that specific house.

Composition is a strong HAS-A relationship where the part cannot exist independently of the whole. The whole creates and owns its parts. When the whole is destroyed, all its parts are destroyed. This represents a "part-of" relationship.

UML Notation: Composition vs Aggregation

Composition (Strong)
Car
Engine
Filled diamond = Composition
Engine dies with Car
Aggregation (Weak)
Team
Player
Empty diamond = Aggregation
Player survives Team

2Composition vs Aggregation vs Association

AspectAssociationAggregationComposition
RelationshipUses-AHas-A (weak)Has-A (strong)
OwnershipNonePartialFull
LifecycleIndependentIndependentDependent
Part can exist alone?YesYesNo
UML SymbolPlain lineEmpty diamondFilled diamond

All UML Relationship Symbols

Association
Simple line with arrow (uses/knows)
Aggregation
Empty diamond (weak has-a)
Composition
Filled diamond (strong has-a)
Dependency
Dashed line with arrow (uses temporarily)
Inheritance
Solid line with empty triangle (is-a)
Realization
Dashed line with empty triangle (implements)

3Implementation

Composition Example - Car and Engine
// ========== Composition: Car owns Engine ==========

// Part class - cannot exist without Car
class Engine {
    private String type;
    private int horsepower;

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

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

    public void stop() {
        System.out.println(type + " engine stopping...");
    }
}

// Whole class - creates and owns Engine
class Car {
    private String brand;
    private Engine engine;  // Composition - Car owns Engine

    public Car(String brand, String engineType, int horsepower) {
        this.brand = brand;
        // Car creates Engine - Engine's lifecycle tied to Car
        this.engine = new Engine(engineType, horsepower);
    }

    public void start() {
        System.out.println(brand + " starting...");
        engine.start();  // Delegate to part
    }

    public void stop() {
        engine.stop();
        System.out.println(brand + " stopped.");
    }
}

// Usage
public class Main {
    public static void main(String[] args) {
        Car tesla = new Car("Tesla", "Electric", 450);
        tesla.start();
        tesla.stop();
        
        tesla = null;  // Car destroyed -> Engine destroyed too
    }
}
Output:
Tesla starting...
Electric engine starting...
Electric engine stopping...
Tesla stopped.
(In C++: Engine destroyed, Car destroyed)

4Favor Composition Over Inheritance

This is a famous design principle: prefer composing objects over inheriting from classes.

Composition Benefits
  • Change behavior at runtime
  • Loose coupling
  • Easy to test (inject mocks)
  • No diamond problem
  • More flexible
Inheritance Drawbacks
  • Behavior fixed at compile time
  • Tight coupling to parent
  • Hard to test in isolation
  • Diamond problem in multiple inheritance
  • Fragile base class problem
When to Use Each
  • Inheritance: True IS-A relationship (Dog IS-A Animal)
  • Composition: HAS-A relationship (Car HAS-A Engine)
  • When in doubt, prefer composition. It is more flexible and maintainable.

5Interview Follow-up Questions

Interview Follow-up Questions

Common follow-up questions interviewers ask

6Key Takeaways

1Composition = strong HAS-A where part cannot exist without whole.
2Part lifecycle is tied to whole - destroyed together.
3Aggregation = weak HAS-A where part can exist independently.
4Favor composition over inheritance for flexibility.
5UML: Filled diamond for composition, empty for aggregation.
6Examples: Car-Engine (composition), Team-Player (aggregation).