Python OOP – Multiple Inheritance

In this Python article, we will study multiple inheritance along with its implementation and lots of examples in detail. Let’s get started.

1. What is Multiple Inheritance in Python?

In python, there are various types of inheritance, out of which multiple inheritance has various features.

When we derive a child class using more than one parent class, then it is known as multiple inheritance.

With the help of multiple inheritance, all the attributes and methods of more than one base class can be inherited to the child class.

Syntax:
class Parent1:
  body of parent

class Parent2:
  body of parent

class  child(Parent1, Parent2):
  body of child class
Multiple Inheritance in Python
class Employee:

  def __init__(self, empname, empid):
    self.empname = empname
    self.empid = empid

  def display_name(self):
    print(self.empname)

  def display_id(self):
    return("Employee id", self.empid)


class Engineer:
  def __init__(self, staff_batch):
    self.batch = staff_batch

  def batch_number(self):
    return ("Engineering Batch", self.batch)


class SoftwareEngineer(Employee, Engineer):
  def __init__(self, empname, id_num, batch):
    Employee.__init__(self, empname, id_num)
    Engineer.__init__(self, batch)


engineer = SoftwareEngineer('Coder', 12, 2021)
engineer.display_name()
print(engineer.display_id())
print(engineer.batch_number())
Output
Coder
('Employee id', 12)
('Engineering Batch', 2021)

Read More about classes and Objects and types of Inheritance in python


2. Conflict with Methods with Multiple Inheritance?

As in the above example, we have used different method names in both the classes, and hence it was easy for the third class company to identify what to take and from which class to take the function.

But what will happen if both the class have the same name for the method. It will become conflicting for the third class company to decide which method has to be taken from both the available option.

class MobileGame:
  def __init__(self):
    self.size = ' 2 GB'
    self.rating = 6

  def dispaly_details(self):
    print("Mobile games")
    print(self.size)
    print(self.rating)


class ComputerGame:
  def __init__(self):
    self.size = '6 GB'
    self.rating = 8

  def dispaly_details(self):
    print("Computer games")
    print(self.size)
    print(self.rating)


class MultiDeviceGame(MobileGame, ComputerGame):
  def __init__(self):
    MobileGame.__init__(self)
    ComputerGame.__init__(self)

  def dispaly_details(self):
    print("Multi-device game")
    print(self.size)
    return(self.rating)


s1 = MultiDeviceGame()
print(s1.dispaly_details())
Output
Multi-device games
6 GB
8

Here, in the above example, the output came from ComputerGame class constructor and not from the MobileGame class. This happens because we have called the constructor of MobileGame first then we called the ComputerGame constructor. Hence all the variables and methods from ComputerGame with the same name will have precedence.

If we revert the order of initialization then the methods and variables will be preferred from another class.

Similarly if we remove the __init__() function then the class which comes first have higher priority. In case of conflicts the class declared first(MobileGame) will have the precedence. Will discuss this in more detail in MRO section.

Once we create the __init__() function inside the child class, the __init__() function of parent child will not be inherited by the child class.

Hence, it can be simply said that __init__() function of a child class overrides the __init__() function of the inherited parent class.


3. What is the Role of MRO in Inheritance Python?

Each and every class which is used in python are derived from one main class known as the object class. In python, this can also be regarded as the highest base type.

It can be said that all the other used classes either it is user-defined or built-in, are derived classes and their instances are the illustration of the object class.

print(isinstance(print,object))

print(issubclass(tuple,object))

print(isinstance(78.5,object))

print(isinstance(7,object))

print(isinstance("Codingeek",object))

print(isinstance(True,object))
Output
True
True
True
True
True
True

While using multiple inheritance, any respective characteristic is first looked for in the class which is currently in use. If the attribute is not found, then the parent classes are searched in a depth-first, left-right manner and it does search a class again.

For example, in the previous program of supergames class, the search will be performed in [MultiDeviceGameMobileGameComputerGameobject] manner.

MRO Illustration

Hence, such order is known as a linearization of MultiDerived class and the rules set which are used to find such order is known as Method Resolution Order (MRO).

MRO must comply with certain limits such as avoiding local precedence orders and providing monotonicity. It ensures that a class always appears before its parents. If a child class has multiple parents, the order remains the same as tuples of base classes.

MRO of a class can be viewed as the __mro__ attribute which returns a tuple or the mro() method which returns a list.

# MRO illustration
class humans:
    pass

class animals:
    pass

class insects:
    pass

class chimeras(humans, animals):
    pass

class insect_animal(animals, insects):
    pass

class disease(insect_animal, chimeras, insects):
    pass

print(disease.mro())
Output
[<class '__main__.disease'>, <class '__main__.insect_animal'>, <class '__main__.chimeras'>, <class '__main__.humans'>, <class '__main__.animals'>, <class '__main__.insects'>, <class 'object'>]

4. Diamond Problem in Python

According to Wikipedia,” The “diamond problem” is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C. If there is a method in A that B and C have overridden, and D does not override it, then which version of the method does D inherit: that of B, or that of C?

In simpler terms, the diamond problem occurs in a combination of hierarchal and multiple inheritance, and the diamond problem is referred to as Hybrid Inheritance.

Diamond Problem

Hybrid inheritance occurs in C++ as well as in java. In python, the diamond problem can be understood by the example below.

class A:
  def method(self):
    print("Class B")


class B(A):
  def method(self):
    print("Class B")


class C(A):
  def method(self):
    print("Class C")


class D(B, C):
  pass

class E(C, B):
  pass


object_D = D()
object_D.method() # Class B

object_E = E()
object_E.method() # Class C
Output
Class B
Class C

In the above example, we can conclude that the preference of the parent class depends on the order of classes defined for inheritance.

When we call object_D.method(), the output was Class B.

When we call object_E.method(), the output was Class A.

Now, let’s call the method for A, B, C using the method “method” of the D. Here below is one example.

class A:
  def method(self):
    print("method A")


class B(A):
  def method(self):
    print("method B")


class C(A):
  def method(self):
    print("method C")


class D(B, C):
  def method(self):
    print("method D")
    A.method(self)
    B.method(self)
    C.method(self)


obj_D = D()
obj_D.method()
Output
method D
method A
method B
method C

In python, with the aid of the super() method to call the immediate parent and it will automatically resolve the parent method.

Declaring the class like class D(C, B) will convert it in structure similar to D extends C, C extends B. so when we call super().method() from C it will refer to class B.

Let’s see how this function.

class A:
  def method(self):
    print("method A")


class B(A):
  def method(self):
    print("method B")
    super().method()


class C(A):
  def method(self):
    print("method C")
    super().method()


class D(C, B):
  def method(self):
    print("method D")
    super().method()


obj_1 = D()
obj_1.method()
Output
method D
method C
method B
method A

5. Conclusion

Finally, if we sum up, in this article we learned about different attributes associated with multiple inheritance along with its implementation and other properties. We have also covered:

  • What is Multiple Inheritance in python?
  • What type of Conflict happens in Multiple Inheritance?
  • Role of MRO in Inheritance Python
  • The diamond problem in Python

Helpful Links

Please follow the Python tutorial series or the menu in the sidebar for the complete tutorial series.

Complete code samples are present on Github project.

An investment in knowledge always pays the best interest. I hope you like the tutorial. Do come back for more because learning paves way for a better understanding

Do not forget to share and Subscribe.

Happy coding!! 😊

Recommended -

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x