Skip to content

Inheritance in Python – A Detailed Explanation with Examples

Inheritance in Python

In this tutorial we will learn about Inheritance in Python . Before reading this tutorial we recommend to read about the below tutorial –

Through inheritance we can create a class that inherits all the methods and properties of another class.

Parent class or base class is the class from which a new class is being created.

The child class or derived class is the class that is being created

Syntax of Inheritance in Python

class base_class:
     statements 

class derived_class(base_class):
     statements 

We can access any property and method of base class using any object of derived class.

Why we need Inheritance in Python?

Inheritance helps us to implement DRY principle in Programming . DRY stands for Don`t Repeat Yourself . Let us try to understand this with an example –

Suppose we have two classes Employee and Programmer . Now we know that all the Programmer is an Employee but all the Employee is not a Programmer . So all the property and method of Employee class will be in Programmer class but Programmer class may have some property or method that will not be in Employee class .

Let`s define both the class without using inheritance –

# without inheritance
# Defining Employee 
class Employee:
    def about(self,name,age):
        self.name=name
        self.age=age
        
# Defining Programmer
class Programmer: 
    def about(self,name,age):
        self.name=name
        self.age=age
       
    def languageKnown(self,language):
        self.language=language

In the above example Employee class has a method named about() . As all the Programmer is an Employee so Programmer class also should have this about() method . Also Programmer class has one extra method named languageKnown() .

Now think about about() method . In both the class definition of about() method is same but we have to define this method in both the class which disrespect the basic principle of programming that is DRY . As here we define only two class so it is not that tough but think if we need to define 100 class which have the same method then what we should do . Now we will solve this problem using inheritance

# with inheritance
# Defining Employee 
class Employee:
    def about(self,name,age):
        self.name=name
        self.age=age
        
# Defining Programmer
class Programmer(Employee):            
    def languageKnown(self,language):
        self.language=language

In the above example when we write class Programmer(Employee) then all the property or method of Employee has been automatically inherited to Programmer class . So we don`t have to define about() method in the Programmer class again . And if we change about() method in the Employee class then it will automatically reflected to the Programmer class .

Type of Inheritance in Python

There are five types of inheritance in Python, which are discussed in detail below –

Single Inheritance in Python

In this type of inheritance a derived class is created from a base class, now we will try to understand it with the help of an example.

Example 1:

# defining a base class
class car:
    # defining a class variable
    no_of_wheel = 4
    # defining a object method
    def start_car (self):
        print("The car has started")
        self.speed = 0
    def drive_car (self):
        print("The car is now running")
        self.speed = 10

The above code defines a base class named car which have a class variable named no_of_wheel (whose value is 4), two object methods named start_car and drive_car and an object variable speed (whose value is 0) will be created after calling start_car method. . And after calling drive_car method, the value of object variable speed will have changed to 10.

Define a derived class using Single inheritance in Python

# defining a derived class
class maruti(car):
    pass

Then a derived class named maruti has been defined which has inherited the car class. No other variables or methods have been defined in the maruti class.

Accessing property or method of base class from derived class object

# creating a object of derived class
brezza = maruti()
# accessing base class variable and method
# from derived class object
print(brezza.no_of_wheel)
brezza.start_car()
print(brezza.speed)
brezza.drive_car()
print(brezza.speed)
4
The car has started
0
The car is now running
10

Here an object of derived class maruti named breeza has been created. Then we have tried to access all the attributes and methods of base class using that object and we have got access .

Example 2:

In the previous example we did not define any property or method in derived class. In this example we will define property or method in derived class and also define constructor in base class.

Note:

When trying to access a method or attribute with an object of a derived class, Python first searches the derived class to see if the method or attribute exists, then go to the base class.

# defining a base class
class car:
    # defining a class variable
    no_of_wheel = 4
    
    # defining a constructor
    def __init__ (self, mileage):
        self.mileage = mileage
        
    # defining a object method
    def start_car (self):
        print("The car has started")
        self.speed = 0
    def drive_car (self):
        print("The car is now running")
        self.speed = 10

The above code defines a base class named car which have a class variable named no_of_wheel (whose value is 4), two object methods start_car and drive_car .We have also defined a constructor which creates an object variable called mileage whose value equals the value of mileage given as argument . After calling start_car method an object variable speed (whose value is 0) will be created and after calling drive_car method, the value of object variable speed will have changed to 10.

# defining a derived class
class maruti(car):
    # creating a object method
    def start_car (self):
        print("The maruti has started")
        self.speed = 0  
    def accelerate(self):
        print("accelerate the maruti")
        self.speed += 10

Then a derived class named maruti has been defined which has inherited the car class. The maruti class has two object methods called start_car and accelerate.

# creating a object  
swift = maruti(80)

# accessing property and methods
print(swift.no_of_wheel)
swift.start_car()
swift.drive_car()
swift.accelerate()
print(swift.speed)     
4
The maruti has started
The car is now running
accelerate the maruti
20

Then an object of maruti class named swift has been created and with its help various methods and attributes have been tried to be accessed.

Notice that the swift object has accessed the start_car method of the maruti class. In fact, when trying to access the start_car method, python first checked the derived class maruti to see if there was any method called start_car, since the derived class maruti had a method named start_car, so Python ran that method. start_car no longer needed to be found in base class.

Note :

We have seen that if the base class and the derived class have two methods or properties with the same name, the object of the derived class can only access the method or property of the derived class. But sometimes we need to access the method or property from the base class . For this reason Python provides a function to solve this problem and that is super().

With the super() function we can access the method or property of the previous base class.

Example 1:
# defining a base class 
class Car:    
    # defining a constructor
    def __init__ (self):
        print("This is base class constructor")

# defining a derived class        
class Maruti(Car):
    def __init__ (self, name):
        print("This is derived class constructor")
        self.name = name
        
# creating a object of derived class maruti
swift = Maruti("Swift")
This is derived class constructor

In the above code we have defined a base class named Car, then defined a derived class named Maruti. Then we made an object swift of Maruti class. Since the __init__ method exists in both the base class and the derived class, the object of the derived class has only run the __init__ method of the derived class.

Example 2:
# defining a base class
class Car:    
    # defining a constructor
    def __init__ (self):
        print("This is base class constructor")
        
# defining a derived class        
class Maruti(Car):
    def __init__ (self, name):
        super().__init__()
        print("This is derived class constructor")
        self.name = name
        
# creating a object of derived class maruti
swift = Maruti("Swift")
This is base class constructor
This is derived class constructor
  • The difference between the above code and the aforesaid code is that we have used super() function in the constructor of Maruti derived class of the above code.
  • Since the constructor of the base class has no parameter other than self, the __init__ method has been called without any parameter with the help of super() function in derived class.
  • When the object of the derived class is created, the constructor of the derived class is automatically called. Since the first line in the derived class constructor is calling the constructor of the base class, so the constructor of the base class will run first, then rest part of the derived class constructor will run.

Multilevel Inheritance in Python

When a derived class from a base class and another derived class from that derived class are created and the process continues, it is called Multilevel inheritance.

Syntax of Multilevel Inheritance in Python

class base_class:
     statements 

class derived_class1(base_class):
     statements 

class derived_class2(derived_class1):
     statements

Example 1:

# Multilevel inheritance
# defining a base class
class Father:
    def __init__ (self, name):
        self.name = name
    def hobby (self):
        print("solving c++ problem")

In the above code, a base class named Father is defined with a constructor which have only one parameter except self. After the object is created an object variable named name will be created, also the class has an object method called hobby.

# defining a derived class Son
# from base class Father
class Son(Father):
    def __init__ (self, name):
        super().__init__(name)
    def hobby (self):
        print("solving java problems")
        super().hobby()   

Then a derived class Son is defined from the base class Father . In the Son class constructor the constructor of the base class Father is called through the super() function . Since Father class constructor has one parameter except self so when we called Father class constructor from Son class constructor we need to pass one argument in the __init__ method .

There is also an object method called hobby and in it also the object method hobby of base class Father has been called through super() function.

Define a derived class using Multilevel inheritance in Python

# defining a derived class Grandson
# from derived class Son
class Grandson(Son):
    def __init__ (self, name):
        super().__init__(name)
    def hobby (self):
        print("solving python problems")
        super().hobby()

Then a derived class Grandson is defined from the derived class Son . In the <code>Grandson class constructor the constructor of the derived class Son is called through the super() function . There is also an object method called hobby and in it also the object method hobby of derived class Son has been called through super() function.

# creating a object of derived class Grandson
rajkumar = Grandson("Rajkumar")
print(rajkumar.name)
rajkumar.hobby()
Rajkumar
solving python problems
solving java problems
solving c++ problem
  • Then an object of the Grandson class named rajkumar has been created with argument as “Rajkumar” .
  • Now the constructor of Grandson class will be called first, since the super() function has been used, the constructor of Son class will also be called . Since the super() function also has been used in Son‘s class constructor so parent of Son class that is Father‘s class constructor will also be called . As a result a new object variable name with value "Rajkumar" will be created . So when we have printed rajkumar.name , Rajkumar is printed .
  • Then the hobby method of rajkumar object has been called. It will first go to the hobby method of the Grandson class and print whatever is in the print() function, then it will encounter the super() function and go to the hobby method of the previous class Son and print whatever is in the print() function, then it will again face the super() function and go to the previous class Father‘s hobby method and print whatever is in the print() function there.

Multiple Inheritance in Python

When a derived class is defined from two or more base classes, it is called Multiple inheritance. In this case we can access all the properties and methods of each base class with the help of any object of derived class.

Syntax of Multiple Inheritance in Python

class base_class1:
     statements 

class base_class2:
     statements 

class derived_class(base_class1,base_class2):
     statements
Note :
  • In case of multiple inheritance, constructor of base_class1 will run while creating object of derived class.
  • If the same property or method is in base_class1, base_class2 …. etc then the property or method of base_class1 will be called. Later we will understand this matter better with the help of Method resolution order .

Example 1:

#define base class1
class Programmer:
    def __init__ (self, name, language):
        print("Programmer class constructor running")
        self.name = name
        self.language = language
    def greet (self): 
        print("Welcome programmers")
        
#define base class2
class Statistician:
    def __init__ (self, name):
        print("Statistician class constructor running")
        self.name = name
    def greet (self):
        print("Welcome statisticians")
        
#define base class3
class Data_analyzer:
    def __init__ (self, name):
        print("Data analyzer class constructor running")
        self.name = name
    def greet (self):
        print("Welcome data analyzers")

In the above code we have defined three base classes named Programmer, Statistician, Data_analyzer. The constructor of the Programmer class has two parameters except self and the constructor of the other two classes has one parameter except self. Also, each class has an object method called greet.

Define a derived class using Multiple inheritance in Python

#defining a derived class using
#these three base classes
class Data_scientist(Programmer, Statistician, Data_analyzer):
    def __init__ (self, name, language):
        super().__init__(name, language)

We then defined a derived class called Data_scientist through multiple inheritance whose base classes are Programmer, Statistician and Data_analyzer. Since Programmer class is in the first place, when we call the constructor of the previous base class through the super() function in the constructor of the Data_scientist class, it will call the constructor of the Programmer class.

# creating a object of class Data_scientist 
sourav = Data_scientist("sourav", "Python")
#to know method resolution order of sourav object 
print(Data_scientist.mro())
print(Data_scientist.__mro__)
Programmer class constructor running
[<class '__main__.Data_scientist'>, <class '__main__.Programmer'>, <class '__main__.Statistician'>, <class '__main__.Data_analyzer'>, <class 'object'>]
(<class '__main__.Data_scientist'>, <class '__main__.Programmer'>, <class '__main__.Statistician'>, <class '__main__.Data_analyzer'>, <class 'object'>)

Then we created an object of the Data_scientist class called sourav. Here we will learn about Method resolution order. With the help of method resolution order we can clearly understand that if the method or property of the same name is in different base classes then when that method or property is accessed through the object of derived class then the method or property of which class will run.

We have used mro() function and __mro__ attribute with class_name to know the Method resolution order .

By looking at the method resolution order, it is easy to understand that first the derived class Data_scientist and then the order in which we have given the base classes, in the same order these classes will be accessed first i.e. Programmer then Statistician and lastly Data_analyzer.

That is why the constructor of the previous base class of Data_scientist class (i.e. Programmer class) has been run while creating the sourav object.

#accessing method or property
print(sourav.name)
print(sourav.language)
sourav.greet()
sourav
Python
Welcome programmers

When the name and language of the sourav object are printed, sourav and python are printed. But when the greet method was called, according to the method resolution order, it was first checked in the Data_scientist class, when it was not found, then it was checked in the Programmer class. Since the Programmer class has the greet method, the greet method of the programmer class has run.

Hierarchical Inheritance in Python

Hierarchical inheritance defines multiple derived classes from one base class.

Example 1:

#define a base class
class Student:
    def __init__ (self, name, age):
        self.name = name
        self.age = age

In the above code a base class named Student is defined.

Define derived classes using hierarchical inheritance in Python

#define derived class1
class Arts_student(Student):
    def __init__ (self, name, age, subject):
        super().__init__(name, age)
        self.subject = subject        
        
#define derived class2
class Science_student(Student):
    def __init__ (self, name, age, subject):
        super().__init__(name,age)
        self.subject = subject 

Then the two derived classes Arts_student and Science_student are defined . Both of them inherited the Student class.

#creating derived class1 object
sourav = Arts_student("Sourav", 27, "history")
print(sourav.subject)

#creating derived class2 object
rajkumar = Science_student("Rajkumar", 28, "physics")
print(rajkumar.subject)
history
physics

Then one object of each derived class is created and their object variable subject is printed.

Hybrid Inheritance in Python

Hybrid Inheritance is a combination of different types of inheritance.

Example 1:

#define a base class
class Student:
    def __init__ (self, name, age):
        self.name = name
        self.age = age

In the above code a base class named Student is defined.

#heirarchical inheritance from Student       
#define derived class1
class Arts_student(Student):
    def __init__ (self, name, age, subject):
        super().__init__(name, age)
        self.subject = subject        
        
#define derived class2
class Science_student(Student):
    def __init__ (self, name, age, subject):
        super().__init__(name, age, subject)
        self.subject = subject 

Then two derived classes are defined from Student class one is Arts_student and the other is Science_student. So this is a Hierarchical inheritance

Now we will be surprised to see that when the super() function is used in the constructor of Science_student class here, three parameters are used in __init__ whereas only two parameters are used in the constructor of the base class Student except self. But the rule is that if the base class constructor has two parameters other than self, then when the super() function is used in the derived class constructor, then we should use two parameters in __init__ as we have used in the constructor of Arts_student class .

We will solve this problem after creating the object of the last derived class.

#multiple inheritance from
#Arts_student and Science_student
class English_hons_student(Science_student, Arts_student):
    def __init__ (self, name, age, subject):
        super().__init__(name, age, subject)

Then a derived class named English_hons_student has been defined by multiple inheritance from Science_student and Arts_student class.

#single inheritance from English_hons_student
class English_masters_student(English_hons_student):
    def __init__ (self, name, age, subject):
        super().__init__(name, age, subject)

Then from English_hons_student class a new derived class has been defined by single inheritance named English_masters_student.

So we have defined a derived class English_masters_student from Student base class through hierarchical inheritance, multiple inheritance and single inheritance. In other words, we can say that we have defined a derived class English_masters_student from Student base class through hybrid inheritance.

#to know method resolution order        
print(English_masters_student.mro())
[<class '__main__.English_masters_student'>, <class '__main__.English_hons_student'>, <class '__main__.Science_student'>, <class '__main__.Arts_student'>, <class '__main__.Student'>, <class 'object'>]

Then we printed the method resolution order of English_masters_student class with the help of mro() method. From which we can easily see that first English_masters_student then English_hons_student then Science_student then Arts_student and finally Student class.

Now we will solve the above problem, since Science_student is followed by Arts_student as method resolution order, so when we use super() function in Science_student‘s constructor, it will call Arts_student‘s constructor and since Arts_student‘s constructor has three parameters except self so we have used three parameters in __init__ of super() function in Science_student‘s constructor.

#creating a object of class English_masters_student
sudipta = English_masters_student("Sudipta", 28, "English")
#accessing all object variable
print(sudipta.name)
print(sudipta.age)
print(sudipta.subject)
Sudipta
28
English

Then we created an object of English_masters_student named sudipta and printed its various object variables.

Thank you for reading this Article . If You enjoy it Please Share the article . If you want to say something Please Comment .

Leave a Reply