Skip to main content

Command Palette

Search for a command to run...

Inheritance vs 🧩 Composition in Object-Oriented Programming

Design Better Python Classes with These Two Techniques

Published
β€’3 min read
Inheritance vs 🧩 Composition in Object-Oriented Programming
N

Tech lead exploring Generative AI & ML πŸ” | Python, JS, React | Aviation meets Innovation ✈ | Writing what I learn. Learning what I build.

When designing software systems using Object-Oriented Programming (OOP), two powerful techniques to organize and reuse code are inheritance and composition. While both achieve code reuse, they differ significantly in how they model relationships between objects.

Understanding the difference is crucial for building clean, maintainable, and scalable software. Let’s dive into their definitions, use-cases, and differences.


πŸ“˜ What is Inheritance?

Inheritance is when one class (the child/subclass) derives from another class (the parent/base class) and inherits its attributes and methods.

πŸ”— Relationship: "Is-a"

If Dog inherits from Animal, then a Dog is an Animal.

βœ… Example:

class Animal:
    def speak(self):
        print("Animal speaks")

class Dog(Animal):
    def speak(self):
        print("Dog barks")

d = Dog()
d.speak()

πŸ’‘ Output:

Dog barks

Here, Dog overrides the speak() method of Animal, demonstrating method overriding.


🧩 What is Composition?

Composition means that one class contains an instance of another class and delegates work to it. Instead of inheriting, it uses the capabilities of other classes by composing them together.

πŸ”— Relationship: "Has-a"

If Car contains an Engine, then a Car has an Engine.

βœ… Example:

class Engine:
    def start(self):
        print("Engine starts")

class Car:
    def __init__(self):
        self.engine = Engine()

    def start(self):
        self.engine.start()

c = Car()
c.start()

πŸ’‘ Output:

Engine starts

πŸ” Inheritance vs Composition: Head-to-Head

FeatureInheritanceComposition
DefinitionDerives a class from anotherCombines behaviors by containing other objects
Relationship Type"Is-a""Has-a"
CouplingTight coupling to base classLoose coupling, flexible components
Code ReuseThrough class hierarchyThrough object collaboration
FlexibilityLess flexible; base changes ripple to childrenMore flexible; easier to swap or modify parts
Best Used WhenObjects share strong common behaviorYou want to delegate behavior or plug in reusable components
Example Keywordclass B(A):self.obj = SomeOtherClass()

⚠️ Real-World Scenarios

🧬 Inheritance:

Use when there's a clear type hierarchy.

class Person:
    def get_id(self):
        return "Generic ID"

class Employee(Person):
    def get_id(self):
        return "Employee ID"

🧩 Composition:

Use when you want to plug in behaviors or combine functionalities.

class Logger:
    def log(self, msg):
        print(f"Log: {msg}")

class Service:
    def __init__(self):
        self.logger = Logger()

    def run(self):
        self.logger.log("Service started")

🧠 When to Use Which?

Use Inheritance WhenUse Composition When
There's a clear "is-a" relationshipYou want flexibility and modularity
You want to extend a base class’s functionalityYou want to combine behavior from different classes
Code reuse through polymorphism makes senseYou want to favor delegation over tight coupling

🏁 Conclusion

Both inheritance and composition are foundational to OOP, but serve different purposes.

  • Use inheritance for strongly related types that share behavior.

  • Use composition when building modular, flexible systems that need to evolve easily.

In modern software design, especially in large systems, composition is often preferred β€” summarized by the principle:

β€œFavor composition over inheritance.”