0
0
PythonComparisonBeginner · 4 min read

Inheritance vs Composition in Python: Key Differences and Usage

In Python, inheritance means creating a new class based on an existing class to reuse or extend its behavior, while composition means building classes by including instances of other classes to achieve functionality. Inheritance forms an "is-a" relationship, and composition forms a "has-a" relationship.
⚖️

Quick Comparison

Here is a quick side-by-side comparison of inheritance and composition in Python.

FactorInheritanceComposition
Relationship Type"is-a" (e.g., Dog is an Animal)"has-a" (e.g., Car has an Engine)
Code ReuseReuses parent class methods and attributesReuses functionality by including objects
FlexibilityLess flexible, tightly coupledMore flexible, loosely coupled
Change ImpactChanges in parent affect all childrenChanges in components affect only composed objects
Use CaseWhen classes share common behaviorWhen classes combine different behaviors
Design PrincipleFollows class hierarchyFollows object collaboration
⚖️

Key Differences

Inheritance creates a new class by extending an existing class, inheriting its methods and properties. This means the child class automatically has the behavior of the parent class and can override or add new features. It models an "is-a" relationship, like a Dog class inheriting from an Animal class.

Composition builds complex objects by combining simpler objects. Instead of inheriting, a class contains instances of other classes and delegates tasks to them. This models a "has-a" relationship, like a Car class having an Engine object inside it.

Inheritance can lead to tight coupling and fragile code if the parent class changes unexpectedly. Composition encourages loose coupling and better modularity, making it easier to change parts without affecting the whole system.

⚖️

Code Comparison

Here is an example using inheritance to model a Dog that can bark and move.

python
class Animal:
    def move(self):
        return "Moving"

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

my_dog = Dog()
print(my_dog.move())
print(my_dog.bark())
Output
Moving Woof!
↔️

Composition Equivalent

Here is the same example using composition, where Dog has an Animal object to reuse its move method.

python
class Animal:
    def move(self):
        return "Moving"

class Dog:
    def __init__(self):
        self.animal = Animal()
    def bark(self):
        return "Woof!"
    def move(self):
        return self.animal.move()

my_dog = Dog()
print(my_dog.move())
print(my_dog.bark())
Output
Moving Woof!
🎯

When to Use Which

Choose inheritance when you have a clear hierarchical relationship and want to reuse or extend behavior from a base class, such as different types of animals sharing common traits. Use composition when you want more flexibility by combining simple objects to build complex functionality, especially when behaviors can change at runtime or when you want to avoid tight coupling.

In general, prefer composition for better modularity and maintainability, and use inheritance when it naturally fits the problem domain.

Key Takeaways

Inheritance models an "is-a" relationship by extending classes, while composition models a "has-a" relationship by including objects.
Composition offers more flexibility and loose coupling compared to inheritance's tighter coupling.
Use inheritance for clear hierarchies and shared behavior; use composition to combine behaviors and improve modularity.
Changes in parent classes affect all children in inheritance, but composition limits impact to composed objects.
Composition is often preferred for maintainable and flexible code design.