Python Multiple Inheritance Explained with Examples

[ad_1]

In this tutorial, we’ll describe Python Multiple Inheritance concept and explain how to use it in your programs. We’ll also cover multilevel inheritance, the super() function, and focus on the method resolution order.

In the previous tutorial, we have gone through Python Class and Python (Single) Inheritance. There, you have seen that a child class inherits from a base class. However, Multiple Inheritance is a feature where a class can derive attributes and methods from more than one base classes. Hence, it creates a high level of complexity and ambiguity and known as the diamond problem in the technical world. We’ll be taking up this problem later in this tutorial.

A general perception of Multiple Inheritance is that it is either “dangerous” or “bad.” Also, Java doesn’t allow Multiple Inheritance, while C++ does have it. However, Python lays down a mature and well-designed approach to address multiple Inheritance.

Python Multiple Inheritance Explained

Let’s now try to understand the topic in detail.

Please do go through each section carefully to understand these OOPs concepts inside out.

What is Multiple Inheritance?

Python Multiple InheritanceWhen you inherit a child class from more than one base classes, that situation is known as Multiple Inheritance. It, however, exhibits the same behavior as does the single inheritance.

The syntax for Multiple Inheritance is also similar to the single inheritance. By the way, in Multiple Inheritance, the child class claims the properties and methods of all the parent classes.

In Python, the projects and packages follow a principle called DRY, i.e., don’t-repeat-yourself. And Class inheritance is an excellent way to design a class reusing the features of another one and remain DRY.

Basic Python Multiple Inheritance Example

"""
 Desc:
  Python program to demonstrate the diamond problem
  (a.k.a. Multiple Inheritance)
"""

# Parent class 1
class TeamMember(object):                   
   def __init__(self, name, uid): 
      self.name = name 
      self.uid = uid 
  
# Parent class 2
class Worker(object):                 
   def __init__(self, pay, jobtitle): 
      self.pay = pay 
      self.jobtitle = jobtitle 
  
# Deriving a child class from the two parent classes
class TeamLeader(TeamMember, Worker):         
   def __init__(self, name, uid, pay, jobtitle, exp): 
      self.exp = exp 
      TeamMember.__init__(self, name, uid) 
      Worker.__init__(self, pay, jobtitle)
      print("Name: {}, Pay: {}, Exp: {}".format(self.name, self.pay, self.exp))

TL = TeamLeader('Jake', 10001, 250000, 'Scrum Master', 5)

The output is:

Name: Jake, Pay: 250000, Exp: 5

Overriding Methods Example

When you define a parent class method in the child, then this process is called Overriding.

In other words, a child class can override methods of its parent or superclass by defining a function with the same name.

However, there are some rules for overriding:

  • The name of the method should be the same and its parameters as well.
  • If the superclass method is private (prefixed with double underscores), then you can’t override it.

In Python, you can use the super() method for overriding. It has the following syntax:

# Override using the super() method
super(class_name, self).override_method_name()

Check the below example.

"""
 Desc:
  Python program to demonstrate overriding
  using the super() method
"""

class base(object): 
   def base_func(self): 
      print('Method of base class')
class child(base): 
   def base_func(self): 
      print('Method of child class')
      super(child, self).base_func() 
class next_child(child): 
   def base_func(self): 
      print('Method of next_child class')
      super(next_child, self).base_func() 

obj = next_child() 
obj.base_func()

The result is:

Method of next_child class
Method of child class
Method of base class

What is Multi-level Inheritance?

Python Multilevel InheritanceWhen you inherit a class from a derived class, then it’s called multilevel inheritance. And, it can go up any levels in Python.

In multilevel inheritance, properties of the parent and the child classes are available to the new class.

Multilevel inheritance is akin to the relationship between grandpa, father, and the child. You can sense it in the below examples.

  • A car derives from the vehicle, which itself belongs to the automobile class.
  • An inverter AC is a subclass of the AC class, which relates to the Appliance superclass.

Below is a simple illustration depicting the multilevel inheritance.

class parent:
    pass
class child(parent):
    pass
class next_child(child):
    pass

You can observe the following by looking at the above code:

  • The child class is a derivative of the parent.
  • The next_child class is a derivative of the child.

Python Multi-level Inheritance Example

"""
 Desc:
  Python program to demonstrate multilevel inheritance
"""
class Team:
   def show_Team(self):
      print("This is our Team:")

# Testing class inherited from Team
class Testing(Team):
   TestingName = ""

   def show_Testing(self):
      print(self.TestingName)
 
# Dev class inherited from Team
class Dev(Team):
   DevName = ""

   def show_Dev(self):
      print(self.DevName) 
 
# Sprint class inherited from Testing and Dev classes
class Sprint(Testing, Dev):
   def show_parent(self):
      print("Testing :", self.TestingName)
      print("Dev :", self.DevName)

s1 = Sprint()  # Object of Sprint class
s1.TestingName = "James"
s1.DevName = "Barter"
s1.show_Team()
s1.show_parent()

The output is:

This is our Team:
Testing : James
Dev : Barter

Python Multiple Inheritance vs. Multi-level Inheritance

The primary differences between Multiple and Multilevel Inheritance are as follows:

  • Multiple Inheritance denotes a scenario when a class derives from more than one base classes.
  • Multilevel Inheritance means a class derives from a subclass making that subclass a parent for the new class.
  • Multiple Inheritance is more complex and hence not used widely.
  • Multilevel Inheritance is a more typical case and hence used frequently.
  • Multiple Inheritance has two classes in the hierarchy, i.e., a base class and its subclass.
  • Multilevel Inheritance requires three levels of classes, i.e., a base class, an intermediate class, and the subclass.

Multiple vs. Multilevel Inheritance

Method Resolution Order (MRO)

Method Resolution Order (MRO) is an approach that a programming language takes to resolve the variables or methods of a class.

Python has a built-in base class named as the object. So, any other in-built or user-defined class which you define will eventually inherit from it.

Now, let’s talk about how the method resolution order (MRO) takes place in Python.

  • In the multiple inheritance use case, the attribute is first looked up in the current class. If it fails, then the next place to search is in the parent class, and so on.
  • If there are multiple parent classes, then the preference order is depth-first followed by a left-right path, i.e., DLR.
  • MRO ensures that a class always precedes its parents and for multiple parents, keeps the order as the tuple of base classes.

Basic MRO Example

"""
 Desc:
  Python program to demonstrate how MRO resolves
  a method or an attribute
"""

class Heap: 
   def create(self): 
      print(" Creating Heap") 
class Node(Heap): 
   def create(self): 
      print(" Creating Node") 

node = Node() 
node.create()

Here is the result:

Creating Node

MRO Example with Multiple Inheritance

"""
 Desc:
  Python program to demonstrate how MRO works
  in multiple inheritance
"""

class Agile: 
   def create(self): 
      print(" Forming class Agile") 
class Dev(Agile): 
   def create(self): 
      print(" Forming class Dev") 
class QA(Agile): 
   def create(self): 
      print(" Forming class QA") 

# Ordering of classes
class Sprint(Dev, QA): 
   pass

sprint = Sprint() 
sprint.create()

Here is the output:

Forming class Dev

In this example, we showcased the Multiple Inheritance, known as Diamond inheritance or Deadly Diamond of Death.

Methods for Method Resolution Order(MRO)

You can check the Method Resolution Order of a class. Python provides a __mro__ attribute and the mro() method. With these, you can get the resolution order.

See the below example:

"""
 Desc:
  Python program to demonstrate how to get
  MRO using __mro__ and mro()
"""

class Appliance: 
   def create(self): 
      print(" Creating class Appliance") 

class AC: 
   def create(self): 
      print(" Creating class AC") 

# Oder of classes
class InverterAC(Appliance, AC): 
   def __init__(self): 
      print("Constructing InverterAC") 

appl = InverterAC() 

# Display the lookup order 
print(InverterAC.__mro__) 
print(InverterAC.mro())

The result is:

Constructing InverterAC
(<class '__main__.InverterAC'>, <class '__main__.Appliance'>, <class '__main__.AC'>, <class 'object'>)
[<class '__main__.InverterAC'>, <class '__main__.Appliance'>, <class '__main__.AC'>, <class 'object'>

Built-in Inheritance Methods in Python

Python gives us two built-in methods to check inheritance. Here, they are:

a. isinstance()

The isinstance() function tests an object type. It returns True or False accordingly.

# Syntax
isinstance(object, class)

Check the below example:

# Python issubclass() example

num = 1.0
print("Is the number {} of float class type? {}".format(num, isinstance(num, float)))

Here is the result:

Is the number 1.0 of float class type? True

b. issubclass()

The issubclass() function tests if a particular class inherits another class or not. It has the following syntax:

# Syntax
issubclass(child_class, parent_class)

It results in True if the given class is actually derived from the parent or returns False otherwise.

"""
 Desc:
  Python program to showcase issubclass() 
"""

class parent(): 
   def __init__(self, x): 
      self.x = x
class child(parent): 
   def __init__(self, x, y): 
      self.y = y 
      parent.__init__(self, x) 

print("Is the child derived from the parent class? {}".format(issubclass(child, parent)))

The result is as follows:

Is the child derived from the parent class? True

After wrapping up this tutorial, you should feel comfortable in using Python Multiple Inheritance. However, we’ve provided you with enough examples to practice more and gain confidence.

Also, to learn Python from scratch to depth, do read our step by step Python tutorial.

[ad_2]

Leave a Comment