What is Multiple Inheritance in Python?

Video Tutorial
FREE
Inheritance introduction thumbnail
This video belongs to
Python Course for Beginners With Certification: Mastering the Essentials
16 modules
Certificate
Topics Covered

Before moving on to understand multiple inheritance in Python, let's first take a brief look at the concept of inheritance itself.

When you're born, you look similar to your parents, and that essentially means that you "inherited" the qualities or characteristics of your parents. In the same way, in Python when we talk about classes and objects, we have certain classes (child classes) that we define, which "inherit" from other classes (parent classes). If we create sub-classes of the child classes, they would inherit the properties of the parent class as well.

You can read more about inheritance in Python here.

Now let's move on to multiple inheritance in Python. If a child class is inheriting the properties of a single other class, we call it single inheritance. However, if a child class inherits from more than one class, i.e. this child class is derived from multiple classes, we call it multiple inheritance in Python. This newly derived child class will inherit the properties of all the classes that it is derived from. A very simple real life example would be the one discussed above - a child inheriting properties of the father and mother.

Take a look at this image to understand the concept better:

example of Multiple Inheritance in Python

Syntax of Multiple Inheritance in Python

Moving on to the syntax of multiple inheritance in Python, it is much similar to that of single inheritance. For this example, we're not adding any code to the class, the 'pass' statement will simply skip the code and move ahead.

Here, we have defined two classes which would be the parent classes of our new derived class. The derived class will have the properties of BaseClass1 as well as BaseClass2 as specified in the code above, i.e. the child has properties of both parents. Let us now look at an example of multiple inheritance in Python.

Multiple Inheritance in Python Example

We had taken a simple example in the beginning to understand the basic concept of inheritance - the inheritance of characteristics of parents by the child. Let's try to implement this same example in code to demonstrate multiple inheritance in Python.

For this example, we will create two parent classes -- the father class, and the mother class. Each of these classes will have its own methods. Post that, we will create a child class that inherits from both the classes. We will then try to call the functions of the parent classes from the derived class (child class) object. Here's how it will be done in Python:

Output:

As we can see in the output, the child class that was derived from Dad() and Mom() classes have the properties of both the parent / base classes.

The Diamond Problem

The diamond problem is a typical problem that is faced in multiple inheritance in Python. It is essentially an ambiguity that is arisen when there are two classes say B and C that inherit / are derived from a single class A, and there is another class D, that is a class derived from multiple inheritance and inherits from B as well as C. Take a look at this visualization for a better understanding:

The Diamond Problem

As seen in this diagram, the description of the inheritance structure creates the shape of a diamond and hence this problem is called the diamond problem. But why is this a problem?

This is a problem, because, as mentioned above, there is an ambiguity that arises -- which methods should the class D inherit? It might also happen that multiple copies of the objects of the parent class - A would be inherited by the child class D.

Let's take an example to understand better. We're going to create the 4 classes person, father, mother, and child as in the structure above. The classes - father and mother would be derived from the person class, and the child class would be derived from both father and mother (multiple inheritance).

With this code, we have created the diamond inheritance structure between the classes person, father, mother, and child. How? The problem is created because when we try to call the display() function that the child_object has inherited from the parent classes, we do not know which display()function would be called. Would it call the father class display function or the mother class display function? In this case, the output shows:

Output:

But why this output? If D inherits properties of both Father and Mother, then why does the display function show "Father called"? Let's try to find the solution to this diamond problem in Python in the next topic.

Method Resolution Order in Python

The ambiguity that we noticed in the diamond problem, is something that becomes irrelevant once we talk about the "Method Resolution Order" in Python. This method resolution order is essentially an order in which a particular method is searched for in the hierarchy of classes in the case of inheritance.

Now, how do we check this order? This can be done by the usage of the __mro__ attribute on the class that is derived from multiple classes i.e. child class, in this case.

Here's how we would do it:

Output:

Now here, in this order, we can observe that the class 'father' comes before the class 'mother'. This means that if we call the display() method on the class child, the python interpreter will invoke the display method of class 'father'.

If we run the code that we wrote above -- the one with 4 classes, we can see in the output, that the class called was as per the order given by the __mro__ attribute.

Output:

The Father class was called. So, when there is multiple inheritance involved in a class, and if the names of the methods in the classes conflict (like the display() method here), then the name that was mentioned during the initialization of the derived class first (father class here) will be invoked first.

If we had created the child class like this:

then, in the __mro__ attribute, the order would have contained the Mother class first, and on calling the display() method, the output would have been:

Output:

The Super Function

This super() function is useful when it comes to avoiding the use of the base class / parent class explicitly. Since Python is a dynamic language, the super() function is called dynamically unlike in other languages. The super() function can be used in both multiple as well as single inheritance.

Let's take an example to understand this better. If we have our subclass (child class here), and we would like to refer to the parent class, we can make use of the super() function. Using the super() function, we can get a temporary object of the parent class / superclass, and this way, we can get access to all of the methods of the superclass to its child class.

A point to note here is that when we are using the super() function, we need not specify the name of the superclass to access its methods.

To know more about the super() function, refer to this.

Continuing our example of the family, take a look at this example using the super() function:

Output:

This way, using the super() function we were able to access the methods of the superclasses.

More Examples

Let's take a look at some more examples of multiple inheritance. We're now going to implement vehicles as classes.

We will declare 5 base classes namely - Bike, Car, Truck, Bus, and Plane. From these 5 base classes, we will write down a derived class called - Transport since these are some of the vehicles that we use for transport. Let's code it up:

Code:

Output:

As we can see in the output, when we created an object of the derived class, we were also able to access the methods of the parent classes. This is the main concept of multiple inheritance.

Let's now consider some scenarios in multiple inheritance in Python as more examples.

When the Method is Overridden in Both Classes

In this scenario, we're going to create 4 classes in the same structure as that of the diamond problem and observe what happens if we create the same method, and override it in both classes i.e., we're going to write the same function that exists in the parent class, in both the base classes.

What do you think the output should be? Remember we studied the concept of 'mro' - method resolution order? According to that, the output should be - "In Base class 1" since we put the name of base class 1 before base class 2 in the classes that the derived class inherits from.

Output:

When the Method is Overridden in One of the Classes

In this scenario, unlike the previous one, we're only going to override the method (write the same function) in one of the base classes, and for the other class, we will simply 'pass'. Let's observe the output.

Output:

We received this output because, initially, according to 'mro' (method resolution order), the object called BaseClass1, however, the only code existing was "pass", which is why it then executed the method function() from the class where it was defined - BaseClass2.

Click here to know more about Method Overriding in Python.

When Every Class Defines the Same Method

What would happen if we have the same method - function() in all of the classes including the derived class i.e. we override the method in both the base classes? Would the output be according to method resolution order? Let's find out:

Output:

This time, the method - function was called from the child class itself. We have executed the method 'function' of the ChildClass, since this method overrides the method of its parent classes. If you would like to call the method - function() method of the remaining classes, you could do so the following way:

Output:

Pros and Cons of Multiple Inheritance

You've now learned all there is to multiple inheritance in Python, let's also discuss some of its pros and cons.

Pros:

  • With the help of multiple inheritance a class can inherit the properties of more than one class hence providing more functionality.
  • The classes are categorized in multiple ways. For example, during analysis, we can use the concept of multiple inheritance to capture the way different objects are classified by users.
  • If we have multiple superclasses, the new derived class can reuse the attributes that it has inherited from the parent classes.

Cons:

  • Sometimes it can lead to confusion if the two base classes have a method with the same name (diamond problem)
  • With a higher number of superclasses, the maintenance of code is higher. You may have to make changes in the derived class if you change one of the parent classes / superclass.

Conclusion

  • If a child class inherits from more than one class, i.e. this child class is derived from multiple classes, we call it multiple inheritance in Python.
  • Syntax of multiple inheritance in Python:
  • Here the derived class (product of multiple inheritance) is class C.
  • The diamond problem is an ambiguity that is arisen when there are two classes say B and C that inherit / are derived from a single class A, and there is another class D, that is a class derived from multiple inheritance and inherits from B as well as C.
  • The ambiguity of the diamond problem does not exist in python since we have the __mro__ attribute -- Method Resolution Order.
  • Python has the super() function which is used to avoid the use of the base class or the parent class explicitly.
  • A few cases in multiple inheritance:
  • When the method is overridden in both classes, the output is printed according to the method resolution order.
  • When the method is overridden in only one of the classes, the output is the function of the class that overrides the method.
  • When all the classes define the same method, the output is the result of the code in the child class (derived class).

See Also: