OOP - Inheritance Vs Composition
Updated: Sep 30, 2025
Problem
This problem was asked by Google.
Explain the difference between composition and inheritance. In which cases would you use each?
Conceptual Comparison Table
| Feature | Inheritance | Composition |
|---|---|---|
| Relationship | "is-a" (Dog is an Animal) | "has-a" (Garage has a BikeContainer) |
| How it works | Subclass extends and reuses parent behavior | Class includes other objects as components |
| Code reuse | Shares and customizes parent functionality | Shares features by delegating to components |
| Flexibility | More rigid, tightly coupled | More flexible, loosely coupled |
| Change impact | Parent changes affect all children | Component changes affect only owner |
| Example | Employee inherits from Person | Car contains an Engine |
| Best for | Hierarchies, shared logic | Modular, interchangeable parts |
| Drawbacks | Can create fragile, deep hierarchies | May require more setup and delegation |
Conceptual Explanation
- Inheritance lets a class build on top of another, inheriting its properties and methods. Use it when you have a clear "is-a" relationship and want to extend or specialize behavior. For example, a
Dogis anAnimal. - Composition means a class is made up of other classes, using their features. Use it for "has-a" relationships and when you want to assemble objects from reusable parts. For example, a
Carhas anEngine.
Practical Examples
Inheritance Example
class Animal:
def speak(self):
return "Some sound"
class Dog(Animal):
def speak(self):
return "Woof!"
Composition Example
class Engine:
def start(self):
return "Engine started"
class Car:
def __init__(self):
self.engine = Engine()
def start(self):
return self.engine.start()
When to Use Each
- Use inheritance when:
- There is a clear hierarchy and shared logic
- You want to extend or specialize an existing class
- Example:
Birdinherits fromAnimal
- Use composition when:
- You want to build complex objects from simple, reusable parts
- You need flexibility and loose coupling
- Example:
Computerhas aCPU,Memory, andStorage
Best Practices
- Favor composition for flexibility and maintainability
- Use inheritance only when the "is-a" relationship is clear and justified
- Avoid deep inheritance chains to keep code simple
- Use composition to enable code reuse and interchangeable components
Which One to Choose?
To decide between inheritance and composition:
- Prefer inheritance for "is-a" relationships, where a class should expose the full interface of its parent.
- Prefer composition for "has-a" relationships, where a class is built from other components.
Dog < Animal Use inheritance for is-a.
Van(BikeContainer)
Garage(BikeContainer) Use composition for has-a.
Dock(BikeContainer)
A dog is an animal, but a garage is not a bike container—it has a bike container. So, BikeContainer should be a module or component that other classes use.
- Both inheritance and composition allow code reuse.
- Public Inheritance
- "is-a" relationship
- Employee is a Person
- Checking Account is an Account
- Circle is a Shape
- "is-a" relationship
- Composition / Association
- "has-a" relationship
- Person has an Account
- Player has a Special Attack
- Circle has a Location
- "has-a" relationship
Best Practices (Summary)
- Prefer composition, but use inheritance when it fits the model.
- Inheritance can make large projects complex, especially with multiple inheritance.
- Be careful of namespace collisions with inheritance.
- Good design up front helps you use inheritance effectively, but composition is often quicker to implement and easier to maintain.