Python Multiple Inheritance With Examples

We are going to learn about python multiple inheritance today. Before starting multiple inheritance, I suggest you to skim through Python Class and Python Inheritance if you are not familiar with them.

Python Multiple Inheritance

The name says it all. One class extending more than one class is called multiple inheritance. This is one of the cool specialties of python which makes it more convenient than java in some cases (Java doesn’t support multiple inheritance). Java doesn’t have it because at times multiple inheritance may create some ambiguity. We shall talk about it later in this tutorial.

Multiple Inheritance vs Multi-level Inheritance

It may seem confusing if you are familiar with multi-level inheritance before. The main difference between multiple and multi-level inheritance is that, in multi-level inheritance the superclass may also inherit another super class. And in this way, different levels of inheritance can be created among the classes.

multiple-and-multilevel-inheritance

Python Multiple Inheritance Example

Let’s demonstrate a short example of python multiple inheritance.


#definition of the class starts here
class Person:
    #defining constructor
    def __init__(self, personName, personAge):
        self.name = personName
        self.age = personAge
    #defining class methods
    def showName(self):
        print(self.name)
    def showAge(self):
        print(self.age)
    #end of class definition
# defining another class
class Student: # Person is the
    def __init__(self, studentId):
        self.studentId = studentId
    def getId(self):
        return self.studentId
class Resident(Person, Student): # extends both Person and Student class
    def __init__(self, name, age, id):
        Person.__init__(self, name, age)
        Student.__init__(self, id)
# Create an object of the subclass
resident1 = Resident('John', 30, '102')
resident1.showName()
print(resident1.getId())

The classes Person and Student are superclass here and Resident is the subclass. The class Resident extends both Person and Student to inherit the properties of both classes. The example is easily understandable if you have the slightest knowledge of python class and python inheritance. This code yields the following output.


/usr/bin/python3.5 "/home/imtiaz/PycharmProjects/python tutorial - 1/multiple_inheritance.py"
John
102
Process finished with exit code 0

Resolving the Conflicts with python multiple inheritance

Let’s have a look at another example.


class A:
    def __init__(self):
        self.name="John"
        self.age = 23
    def getName(self):
        return self.name
class B:
    def __init__(self):
        self.name="Richard"
        self.id = '32'
    def getName(self):
        return self.name
class C(A, B):
    def __init__(self):
        A.__init__(self)
        B.__init__(self)
    def getName(self):
        return self.name
C1 = C()
print(C1.getName())

Class C inherits both A and B. And both of them has an attribute ‘name’. From which class the value of name will be inherited in C? Is it from A or B? What do you think? Well, the output is:


/usr/bin/python3.5 "/home/imtiaz/PycharmProjects/python tutorial - 1/multiple_inheritance.py"
Richard
Process finished with exit code 0

The name when printed is ‘Richard’ instead of ‘John’. Let’s try to understand what’s happening here. In the constructor of C, the first constructor called is the one of A. So, the value of name in C becomes same as the value of name in A. But after that, when the constructor of B is called, the value of name in C is overwritten by the value of name in B. So, the name attribute of C retains the value ‘Richard’ when printed. The result would be same even if we declared class C as:


Class C(B, A):

The hierarchy becomes completely depended on the order of __init__() calls inside the subclass. To deal with it perfectly, there is a protocol named MRO (Method Resolution Order).

Method Resolution Order (MRO)

Let’s replace the previous code with a slightly modified version.


class A:
    def __init__(self):
        super().__init__()
        self.name="John"
        self.age = 23
    def getName(self):
        return self.name
class B:
    def __init__(self):
        super().__init__()
        self.name="Richard"
        self.id = '32'
    def getName(self):
        return self.name
class C(A, B):
    def __init__(self):
        super().__init__()
    def getName(self):
        return self.name
C1 = C()
print(C1.getName())

Can you guess the output? Well, let’s find out.


/usr/bin/python3.5 "/home/imtiaz/PycharmProjects/python tutorial - 1/multiple_inheritance.py"
John
Process finished with exit code 0

MRO works in a depth first left to right way. super() in the __init__ method indicates the class that is in the next hierarchy. At first the the super() of C indicates A. Then super in the constructor of A searches for its superclass. If it doesn’t find any, it executes the rest of the code and returns. So the order in which constructors are called here is:
C -> A -> B
If we call print(C.__mro__), then we can see the MRO traceroute.


(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)

Once the constructor of A is called and attribute ‘name’ is accessed, it doesn’t access the attribute ‘name’ in B. A better understanding of MRO is a must in order to work with python multiple inheritance.

So this was it for python multiple inheritance, hope to come with more interesting features of python afterwards. Happy Coding!

Reference: Python Doc

By admin

Leave a Reply

%d bloggers like this: