In Object-Oriented Programming (OOP), composition is one of the most powerful and flexible design techniques.
It lets you build complex types by combining objects rather than inheriting from them.
In short:
💬 Composition is when a class contains references to other classes as fields to reuse their functionality.
1️⃣ What Is Composition?
Composition means a “has-a” relationship — a class has another class as part of its state.
For example:
A Car has-a Engine
A Library has-a Book
A House has-a Room
This is different from inheritance, which represents an “is-a” relationship.
2️⃣ Why Use Composition?
Here’s why developers love composition 👇
✨ Advantages:
Promotes code reuse without tight coupling
Allows dynamic behavior changes at runtime
Makes code easier to test and maintain
Avoids the pitfalls of deep inheritance chains
When you can, prefer composition over inheritance — it’s a key OOP principle.
👉 Learn more: Effective Java by Joshua Bloch
(Item 18 covers this in depth).
3️⃣ Composition in Action: Example 🧱
class Engine {
void start() {
System.out.println("Engine started...");
}
}
class Car {
private Engine engine; // Car has-a Engine
Car() {
engine = new Engine();
}
void drive() {
engine.start(); // Using Engine’s behavior
System.out.println("Car is moving...");
}
}
public class Main {
public static void main(String[] args) {
Car car = new Car();
car.drive();
}
}
Output:
Engine started...
Car is moving...
✅ Explanation:
The Car class contains an Engine object and uses its behavior — this is composition in action.
4️⃣ Composition vs Inheritance ⚔️
Here’s a simple way to remember the difference 👇
Composition → “Has-a” relationship
Example: A Car has an Engine.
Inheritance → “Is-a” relationship
Example: A Car is a Vehicle.
Comparison Summary:
Composition gives flexibility
Inheritance gives structure
Composition avoids tight coupling
Inheritance can lead to rigidity in complex hierarchies
💡 Use inheritance when it makes sense logically (“is-a”), and composition for combining reusable behaviors (“has-a”).
5️⃣ When to Use Composition 🧠
Use composition when:
You want to reuse code without inheritance.
Your class logically contains another.
You need runtime flexibility (e.g., swapping components).
You want to avoid diamond inheritance problems.
Example: a Computer class might contain CPU, Keyboard, and Monitor objects.
6️⃣ Real-World Analogy 🌍
Think of composition like assembling LEGO blocks.
You combine independent, reusable pieces to form something greater.
Each piece (class) has its own responsibility,
and the whole system (composed object) is flexible, maintainable, and modular.
7️⃣ Benefits & Best Practices 💡
✅ Benefits:
Better encapsulation
More maintainable code
Easier unit testing
Flexible and scalable architecture
🧠 Best Practices:
Favor composition for behavior sharing
Avoid deep inheritance hierarchies
Inject dependencies (e.g., via constructors or setters) for easier testing
👉 Check out: Baeldung — Composition vs Inheritance in Java
.
8️⃣ Questions for you ❓
Have you ever replaced inheritance with composition in one of your projects?
What’s your favorite real-world example of composition?
Do you think composition always beats inheritance? Why or why not?
How do you handle dependency injection when using composition?
💬 Final Thoughts
Composition is the foundation of flexible, reusable, and maintainable object-oriented systems.
The next time you design a class, ask yourself:
“Should I inherit from this class, or should I just use it?”
Chances are, composition will be the smarter choice.
Top comments (0)