DEV Community

Mohammed mhanna
Mohammed mhanna

Posted on

🧩 Composition in Java: Building Objects the Smart Way

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();
    }
}
Enter fullscreen mode Exit fullscreen mode

Output:

Engine started...
Car is moving...
Enter fullscreen mode Exit fullscreen mode

✅ 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)