It promotes code reusability, extensibility, and simplifies program structure.
In addition, Polymorphism allows objects of different classes to respond to the same method call in different ways β making your code more flexible and dynamic.
What is Inheritance?
Inheritance is a mechanism in which a new class (called the child or derived class) acquires the properties and methods of an existing class (called the parent or base class).It allows developers to reuse existing code and extend functionality without rewriting it.
Key benefits:
- Promotes code reuse
- Supports hierarchical relationships
- Enables polymorphism
Basic Syntax of Inheritance
The derived class (Child) inherits all attributes and methods from the base class (Parent).class Parent:
# parent class code
pass
class Child(Parent):
# child class code
pass
In Python, the "pass" statement is a null operation. When it is executed, nothing happens. It is used as a placeholder where a statement is syntactically required but no action is desired or needed.
Example: Simple Inheritance
class Animal:
def speak(self):
print("Animals make sounds.")
class Dog(Animal):
def bark(self):
print("Dog barks!")
d = Dog()
d.speak()
d.bark()
Output:
Animals make sounds.
Dog barks!
- The Dog class inherits the speak() method from Animal.- This demonstrates how child classes can reuse parent class functionality.
Types of Inheritance in Python
| Type | Description |
|---|---|
| Single Inheritance | Child class inherits from one parent class |
| Multiple Inheritance | Child class inherits from more than one parent class |
| Multilevel Inheritance | A class inherits from a child class, forming a chain |
| Hierarchical Inheritance | Multiple child classes inherit from a single parent |
| Hybrid Inheritance | Combination of two or more inheritance types |
Single Inheritance
In single inheritance, a child class inherits from one parent class.class Parent:
def display(self):
print("This is the Parent class")
class Child(Parent):
def show(self):
print("This is the Child class")
obj = Child()
obj.display()
obj.show()
Output:
This is the Parent class
This is the Child class
The child class can access both its own and parent class methods.
Multiple Inheritance
In multiple inheritance, a class can inherit from multiple parent classes.class Father:
def skills(self):
print("Father: Gardening, Cooking")
class Mother:
def talents(self):
print("Mother: Painting, Singing")
class Child(Father, Mother):
def hobbies(self):
print("Child: Coding, Dancing")
c = Child()
c.skills()
c.talents()
c.hobbies()
Output:
Father: Gardening, Cooking
Mother: Painting, Singing
Child: Coding, Dancing
The Child class inherits attributes and methods from both Father and Mother. Python uses a Method Resolution Order (MRO) to decide which parent's method to call when there are name conflicts.
How MRO Works
Python uses a specific algorithm called the C3 Linearization (or C3 superclass linearization) to determine the order in which classes are searched. The MRO ensures:1. Consistency β The order is predictable and follows inheritance hierarchy.
2. Local Precedence Order β A child class is checked before its parent.
3. Left-to-right Rule β When multiple inheritance occurs, Python looks for methods from left to right in the base class list.
You can view the MRO using either:
ClassName.__mro__
or
ClassName.mro()
Example: Understanding MRO
In Python, when a class inherits from multiple parent classes, Method Resolution Order (MRO) determines the sequence in which Python searches for methods and attributes in the inheritance hierarchy.class A:
def show(self):
print("Method in A")
class B(A):
def show(self):
print("Method in B")
class C(A):
def show(self):
print("Method in C")
class D(B, C):
pass
# Create object
obj = D()
obj.show()
# Check MRO
print(D.mro())
Method in B
[, , , , ]
Explanation:- The class D inherits from both B and C.
- Both B and C have their own version of the show() method.
- When calling obj.show(), Python follows the MRO: It first looks in D β then B β then C β then A β finally object.
- It finds the show() method in B first and executes it.
Multilevel Inheritance
In multilevel inheritance, a class inherits from another derived class, forming a hierarchy.class Grandparent:
def show_grandparent(self):
print("This is the Grandparent class")
class Parent(Grandparent):
def show_parent(self):
print("This is the Parent class")
class Child(Parent):
def show_child(self):
print("This is the Child class")
obj = Child()
obj.show_grandparent()
obj.show_parent()
obj.show_child()
Output:
This is the Grandparent class
This is the Parent class
This is the Child class
- The Child class inherits from both Parent and Grandparent.- This forms an inheritance chain.
Method Overriding
When a child class defines a method with the same name as one in the parent class, the child class method overrides the parent method.class Animal:
def sound(self):
print("Animals make sounds")
class Dog(Animal):
def sound(self):
print("Dogs bark")
d = Dog()
d.sound()
Output:
Dogs bark
- The sound() method in the Dog class overrides the one in Animal.- This is a fundamental part of Polymorphism.
Using super()
The super() function is used to call a method from the parent class inside the child class. It's useful when you want to extend the parent's functionality without completely replacing it.class Parent:
def show(self):
print("This is the Parent class method")
class Child(Parent):
def show(self):
super().show() # call parent method
print("This is the Child class method")
obj = Child()
obj.show()
Output:
This is the Parent class method
This is the Child class method
- super() ensures that both parent and child versions of the method are executed.- It's also commonly used in constructors (__init__()).
Constructor Overriding Example
class Parent:
def __init__(self):
print("Parent constructor called")
class Child(Parent):
def __init__(self):
super().__init__() # Call parent constructor
print("Child constructor called")
obj = Child()
Output:
Parent constructor called
Child constructor called
- super().init() allows the parent constructor to run before the child's initialization.
Polymorphism in Python
Polymorphism means "many forms." It allows objects of different classes to be treated as if they are of the same type, as long as they implement the same interface (methods).Example: Polymorphism Using Method Overriding
class Bird:
def fly(self):
print("Most birds can fly")
class Sparrow(Bird):
def fly(self):
print("Sparrows fly swiftly")
class Ostrich(Bird):
def fly(self):
print("Ostriches cannot fly")
birds = [Bird(), Sparrow(), Ostrich()]
for b in birds:
b.fly()
Output:
Most birds can fly
Sparrows fly swiftly
Ostriches cannot fly
- The same method name (fly()) behaves differently based on the object type.- This is runtime polymorphism in action.
Example: Polymorphism with Functions
Polymorphism also works with functions that accept different object types.class Cat:
def sound(self):
print("Meow")
class Dog:
def sound(self):
print("Bark")
def make_sound(animal):
animal.sound()
make_sound(Cat())
make_sound(Dog())
Output:
Meow
Bark
The function make_sound() calls the same method name on different objects β demonstrating polymorphism.
No Traditional Method Overloading in Python
Python does not support traditional compile-time method overloading (like Java or C++). When you define two methods with the same name in a class, the last definition overrides the earlier one. So in the below example:def print_name(self, first_name, last_name): ...
def print_name(self, full_name): ...
The second print_name() completely replaces the first one.
class Student:
def print_name(self, first_name, last_name):
print(f"{first_name} {last_name}")
def print_name(self, full_name):
print(full_name)
s = Student()
s.print_name("John Doe") # This will work correctly
s.print_name("John", "Doe") # This will raise a TypeError
Summary
Inheritance and Polymorphism together form the backbone of OOP in Python. They make your code more modular, maintainable, and extensible by allowing classes to build on existing functionality.| Concept | Description |
|---|---|
| Inheritance | Mechanism for reusing code by deriving new classes from existing ones |
| Single Inheritance | Child inherits from one parent class |
| Multiple Inheritance | Child inherits from multiple parents |
| Multilevel Inheritance | Inheritance chain between classes |
| Method Overriding | Redefining a parent class method in the child class |
| super() | Calls parent class methods or constructors |
| Polymorphism | Same method name behaves differently for different classes |
| Constructor Overriding | Child class defines its own constructor while optionally calling the parentβs |
- Use Polymorphism when you want to write flexible code that works with objects of multiple types.
In the next article, we'll explore Abstraction and Interfaces in Python β how to design clean, minimal, and secure class structures using abstract base classes (ABC).