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
| Aspect | Association | Aggregation | Composition |
|---|---|---|---|
| Relationship | Uses-A | Has-A (weak) | Has-A (strong) |
| Ownership | None | Partial | Full |
| Lifecycle | Independent | Independent | Dependent |
| Part can exist alone? | Yes | Yes | No |
| UML Symbol | Plain line | Empty diamond | Filled 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).