OOP - Inheritance Vs Composition

Problem (Daily Coding Problem 389)

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 Dog is an Animal.
  • 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 Car has an Engine.

Practical Examples

Inheritance Example

1
2
3
4
5
6
7
class Animal:
    def speak(self):
        return "Some sound"

class Dog(Animal):
    def speak(self):
        return "Woof!"

Composition Example

1
2
3
4
5
6
7
8
9
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: Bird inherits from Animal
  • Use composition when:
    • You want to build complex objects from simple, reusable parts
    • You need flexibility and loose coupling
    • Example: Computer has a CPU, Memory, and Storage

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:

  1. Prefer inheritance for “is-a” relationships, where a class should expose the full interface of its parent.
  2. Prefer composition for “has-a” relationships, where a class is built from other components.
1
2
3
4
5
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
  • Composition / Association
    • “has-a” relationship
      • Person has an Account
      • Player has a Special Attack
      • Circle has a Location

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.