Interview Q&A / Object-Oriented Programming

IntermediateIn-depth3 min readUpdated 2 Oct 2026

What is the difference between composition and inheritance, and when would you prefer composition?

SHORT ANSWER

Inheritance is an "is-a" relationship where a class extends another and reuses its code. Composition is a "has-a" relationship where a class holds other objects and delegates work to them. Prefer composition by default because it keeps classes loosely coupled and lets you swap behaviour, and use inheritance only for a true, stable "is-a" relationship.

Explain it simply

A smartphone has a camera, a battery and a SIM slot. It is not a camera. If a better camera comes out, the manufacturer swaps the module and the phone still works. That is composition: build something by putting parts together.

A Royal Enfield Classic is a motorcycle. It automatically gets everything a motorcycle has: wheels, an engine, brakes. That is inheritance. It works well when the relationship is real and does not change. It goes wrong when you force it, like saying a phone "is a" camera just to reuse the click-photo feature.

Example

java
// Inheritance: tightly tied to the parent
class Vehicle {
    String start() { return "Engine started"; }
}
class Car extends Vehicle { }

// Composition: behaviour is a part you plug in
interface Engine { String start(); }

class PetrolEngine implements Engine {
    public String start() { return "Petrol engine started"; }
}
class ElectricMotor implements Engine {
    public String start() { return "Electric motor humming"; }
}

class Scooter {
    private final Engine engine;                 // Scooter HAS an engine
    Scooter(Engine engine) { this.engine = engine; }
    String start() { return engine.start(); }    // delegate the work
}

public class Garage {
    public static void main(String[] args) {
        System.out.println(new Car().start());                       // prints: Engine started
        System.out.println(new Scooter(new PetrolEngine()).start()); // prints: Petrol engine started
        System.out.println(new Scooter(new ElectricMotor()).start());// prints: Electric motor humming
    }
}

The Scooter did not change at all to support an electric motor. With inheritance, you would need a new subclass, and a third variant would need yet another.

How it works

  • Inheritance (extends) copies the parent's public and protected behaviour into the child at compile time. The child depends on the parent's internal details, and a change in the parent can break every child. Java allows only one parent class.
  • Composition stores another object in a field and forwards calls to it. The outer class depends only on the part's public interface. Parts can be swapped at runtime or replaced with a fake in tests.

Ask one question: "Is the child really a kind of the parent everywhere the parent is used?" If yes, inheritance can fit. If the answer is "it just needs some of that behaviour", use composition.

Real-world use

  • A PaymentService that has a PaymentGateway (Razorpay, Paytm, a mock in tests) instead of extending one of them.
  • Spring and other frameworks inject dependencies through constructors, which is composition.
  • Java's own Stack extends Vector is often cited as a design mistake: a stack should not expose add(index, element), but it inherits it.

Common mistakes

  • Using inheritance only to reuse a couple of methods, which ties the classes together for life.
  • Building deep hierarchies (Animal → Mammal → Dog → Labrador → ServiceLabrador). Every level adds coupling.
  • Thinking composition means never using inheritance. Sharing a contract through an interface and a real "is-a" model, like Circle being a Shape, are fine.

What to say in the interview

"Inheritance models an is-a relationship: the child extends the parent and reuses its code, but it's tightly coupled to the parent's implementation and Java allows only one parent. Composition models a has-a relationship: a class holds other objects, usually through an interface, and delegates to them. I prefer composition by default because I can swap parts, like plugging a different payment gateway into a service, and test with mocks. I use inheritance when the is-a relationship is genuine and stable."

Follow-up questions

  • What is the "fragile base class" problem?
  • How does the Strategy pattern use composition?
  • What is the difference between composition and aggregation?
  • Why does Java not support multiple inheritance of classes?

Go deeper

Read these once the basics above feel easy.

UML separates two kinds of "has-a". In composition, the part cannot live without the whole: an Order's line items are created and destroyed with the order. In aggregation, the part can exist on its own: a Team has Players, but a player still exists if the team is dissolved. In code both look like a field, so the difference is about ownership and lifecycle. The "fragile base class" problem is the main reason to be cautious with inheritance: if a parent's addAll internally calls add, and a child overrides add to count items, the count can be doubled. The child broke because of a parent detail it could not see.

#oop#design#composition#inheritance

Related questions

Practise more Object-Oriented Programming questions

Test your recall with short answers, then return to the detailed explanations when you need context.

Open Object-Oriented Programming quick answers →

Get new questions like this by email

One short email when something new and useful lands. No spam, unsubscribe in one tap.

By subscribing you agree to the Privacy Policy.