Inheritance is a fundamental concept in object-oriented programming (OOP) that allows a class to inherit attributes and methods from another class. This promotes code reusability and helps in creating a hierarchical relationship between classes. Python supports different types of inheritance, each serving a different purpose in software development.
Table of Contents
What is Inheritance?
Inheritance enables a class (child or derived class) to inherit the properties and behavior of another class (parent or base class). This reduces redundancy in the code and helps in better code organization.
Types of Inheritance in Python
Python supports several types of inheritance:
Single Inheritance
In single inheritance, a child class inherits from only one parent class.
class Animal:
def speak(self):
print("Animals make sounds.")
class Dog(Animal):
def bark(self):
print("Dog barks.")
dog = Dog()
dog.speak() # Inherited from Animal
dog.bark() # Defined in Dog
PythonMultiple Inheritance
In multiple inheritance, a child class inherits from multiple parent classes.
class Father:
def skill(self):
print("Good at mathematics.")
class Mother:
def hobby(self):
print("Loves painting.")
class Child(Father, Mother):
def talent(self):
print("Good at coding.")
c = Child()
c.skill()
c.hobby()
c.talent()
PythonHere, Child inherits from both Father and Mother, combining behaviors from both classes.
Multilevel Inheritance
In multilevel inheritance, a class inherits from another class, which itself is a child of another class.
class Grandparent:
def legacy(self):
print("Family legacy.")
class Parent(Grandparent):
def wisdom(self):
print("Parent's wisdom.")
class Child(Parent):
def ambition(self):
print("Child's ambition.")
c = Child()
c.legacy()
c.wisdom()
c.ambition()
PythonHere, Child inherits from Parent, and Parent inherits from Grandparent.
Hierarchical Inheritance
In hierarchical inheritance, multiple child classes inherit from the same parent class.
class Vehicle:
def general_info(self):
print("Vehicles help in transportation.")
class Car(Vehicle):
def car_info(self):
print("Cars have four wheels.")
class Bike(Vehicle):
def bike_info(self):
print("Bikes have two wheels.")
c = Car()
b = Bike()
c.general_info()
c.car_info()
b.general_info()
b.bike_info()
PythonHere, both Car and Bike inherit from Vehicle.
Hybrid Inheritance
Hybrid inheritance is a combination of multiple types of inheritance.
class A:
def methodA(self):
print("Method from Class A")
class B(A):
def methodB(self):
print("Method from Class B")
class C(A):
def methodC(self):
print("Method from Class C")
class D(B, C):
def methodD(self):
print("Method from Class D")
obj = D()
obj.methodA()
obj.methodB()
obj.methodC()
obj.methodD()
PythonHere, D inherits from both B and C, which in turn inherit from A.
Method Resolution Order (MRO)
When multiple inheritance is involved, Python follows the C3 Linearization (MRO) to determine the order in which methods are inherited. Read More
Overriding Methods in Inheritance
A child class can override the methods of its parent class.
class Parent:
def show(self):
print("This is Parent class.")
class Child(Parent):
def show(self):
print("This is Child class.")
obj = Child()
obj.show() # Calls Child's method instead of Parent's
PythonHere, show() in Child overrides show() in Parent.
To access the parent method inside the child class, use super():
class Parent:
def show(self):
print("This is Parent class.")
class Child(Parent):
def show(self):
super().show() # Calls Parent's method
print("This is Child class.")
obj = Child()
obj.show()
PythonUsing super() in Inheritance
The super() function allows you to call a method from the parent class inside the child class.
class A:
def __init__(self):
print("Constructor of A")
class B(A):
def __init__(self):
super().__init__() # Calls A's constructor
print("Constructor of B")
obj = B()
Output
Constructor of A
Constructor of B
PythonBehaviour of __init__ function
Case 1: __init__ in Parent Only
class Parent:
def __init__(self):
print("Parent init")
class Child(Parent):
pass
c = Child()
'''
Parent init
'''
PythonSince Child doesn’t have its own __init__, it inherits and uses the Parent’s __init__
Case 2: __init__ in Child Only
class Parent:
def greet(self):
print("Hello from Parent")
class Child(Parent):
def __init__(self):
print("Child init")
c = Child()
'''
Child init
'''
Python- Parent doesn’t have __init__, so Child’s __init__ runs.
- Parent methods (greet) are still inherited.
Case 3: __init__ in Both Parent and Child (No super())
class Parent:
def __init__(self):
print("Parent init")
class Child(Parent):
def __init__(self):
print("Child init")
c = Child()
'''
Child init
'''
Python- The Child’s __init__ overrides the Parent’s __init__.
- The Parent’s __init__ is not called unless explicitly done
Case 4: __init__ in Both, Child Calls super()
class Parent:
def __init__(self):
print("Parent init")
class Child(Parent):
def __init__(self):
super().__init__()
print("Child init")
c = Child()
Parent init
Child init
Python- super().__init__() calls the Parent’s constructor.
- Then Child continues its own initialization.
Private and Protected Members in Inheritance
- Protected members (_var): Accessible within the class and its subclasses.
- Private members (__var): Not directly accessible outside the class.
In Python, private (__var) and protected (_var) members are just conventions and not strictly enforced like in some other languages (e.g., Java or C++).
class Parent:
def __init__(self):
self._protected = "Protected Attribute"
self.__private = "Private Attribute"
class Child(Parent):
def access(self):
print(self._protected) # Accessible
# print(self.__private) # Will cause an error
obj = Child()
obj.access()
print(obj._protected) # Protected Attribute
print(obj.__private) # Error
PythonPrivate attributes can be accessed using name mangling (_Parent__private).
What is Name Mangling in Python?
- Name mangling is a mechanism used by Python to avoid accidental variable name conflicts in subclasses when dealing with private variables (variables prefixed with double underscores __).
- When you declare a variable with double underscores (__var), Python automatically renames it by prefixing the class name to it. This makes it harder (but not impossible) to access the variable from outside the class.
How Name Mangling Works
Python changes __var to _ClassName__var, so it is still accessible if explicitly referenced using this pattern.
class Parent:
def __init__(self):
self.__private = "This is a private variable"
obj = Parent()
# print(obj.__private) # AttributeError: 'Parent' object has no attribute '__private'
print(obj._Parent__private) # Access using name mangling
PythonConclusion
Inheritance is a powerful OOP concept in Python that promotes code reusability and scalability. Understanding its different types and features like method overriding, super(), and MRO helps in writing efficient and organized programs.
1 thought on “Understanding Inheritance in Python”