Python Inheritance Explained: Types, super() & MRO (Method Resolution Order)
Inheritance is one of the most powerful features of Object-Oriented Programming (OOP).
It allows a class (child or subclass) to reuse the properties and behaviors (methods and attributes) of another class (parent or superclass).
In simple terms —
Inheritance enables code reusability and hierarchical relationships between classes.
Why Inheritance Is Used
✅ To reuse existing code instead of rewriting it.
✅ To extend or modify behavior of existing classes.
✅ To create hierarchies that represent “is-a” relationships (e.g., Car is a Vehicle).
✅ To make code easier to maintain and organize.
Basic Inheritance
When one class inherits another, it automatically gains access to the parent class’s methods and attributes.
Example:
class Vehicle:
def start(self):
print("Vehicle started")
class Car(Vehicle): # Car inherits from Vehicle
def start(self):
print("Car engine started")
c = Car()
c.start()
Output:
Car engine started
✅ Explanation:
- The Car class inherits all features of Vehicle.
- However, it overrides the start() method to provide its own implementation.
This is called method overriding.
Using super()
When you override a method in a child class, you can still access the parent’s version of that method using super().
Example:
class Vehicle:
def start(self):
print("Vehicle started")
class Car(Vehicle):
def start(self):
super().start() # call parent version
print("Car engine started")
c = Car()
c.start()
Output:
Vehicle started
Car engine started
✅ Explanation:
- super().start() calls the start() method of the parent class (Vehicle).
- It ensures that both the parent and child actions are performed.
Why super() Is Important
- Helps extend parent functionality instead of fully replacing it.
- Ensures cooperative multiple inheritance (explained below).
- Reduces code duplication and increases clarity.
Types of Inheritance in Python
Python supports several types of inheritance:
| Type | Description | Example |
|---|---|---|
| Single Inheritance | Child class inherits from one parent class | class B(A): pass |
| Multiple Inheritance | Child class inherits from more than one parent class | class C(A, B): pass |
| Multilevel Inheritance | A class inherits from another derived class | A → B → C |
| Hierarchical Inheritance | Multiple child classes inherit from a single parent class | B(A), C(A) |
| Hybrid Inheritance | A combination of multiple inheritance types | A → B, A → C, B & C → D |
Example of Multiple Inheritance
class A:
def show(self):
print("Class A")
class B:
def show(self):
print("Class B")
class C(A, B):
pass
c = C()
c.show()
Output:
Class A
✅ Explanation:
- Class C inherits from both A and B.
- When calling c.show(), Python follows the Method Resolution Order (MRO) to decide which method to call first.
- Since A appears first in the inheritance list, its method is used.
MRO (Method Resolution Order)
MRO determines the order in which Python searches for a method or attribute when it is called on an object.
It is crucial for resolving ambiguity in multiple inheritance situations.
Python follows the C3 linearization algorithm (also called C3 superclass linearization) to compute the MRO.
Example:
class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass
print(D.mro())
Output:
[, , , , ]
✅ Explanation:
- The search order is D → B → C → A → object.
- If a method is not found in D, Python looks in B, then C, then A, and finally in object.
The Diamond Problem
The diamond problem occurs when multiple inheritance creates ambiguity —
a class inherits from two classes that both inherit from the same base class.
Example diagram:
A
/ \
B C
\ /
D
If all classes have the same method (say show()), Python must decide which one to call when you call D.show().
Example:
class A:
def show(self):
print("A")
class B(A):
def show(self):
print("B")
class C(A):
def show(self):
print("C")
class D(B, C):
pass
d = D()
d.show()
print(D.mro())
Output:
B
[, , , , ]
✅ Explanation:
- D inherits from both B and C.
- The MRO ensures a consistent and predictable order: D → B → C → A → object.
- Therefore, B.show() is called first.
This MRO ordering solves the diamond problem by removing ambiguity.
The Role of super() in Multiple Inheritance
When using multiple inheritance, super() doesn’t just call the immediate parent —
it calls the next class in the MRO chain.
This makes it possible for all parent classes to cooperate rather than override each other completely.
Example:
class A:
def show(self):
print("A")
class B(A):
def show(self):
super().show()
print("B")
class C(A):
def show(self):
super().show()
print("C")
class D(B, C):
def show(self):
super().show()
print("D")
d = D()
d.show()
Output:
A
C
B
D
✅ Explanation:
- Python follows the MRO chain: D → B → C → A → object
- super() ensures that each class’s version of show() is executed once in the correct order.
