Dev Genius

Coding, Tutorials, News, UX, UI and much more related to development

Follow publication

Multiple Inheritance in Python (48/100 Days of Python)

--

Day 48 of the “100 Days of Python” blog post series covering multiple inheritance in Python

Multiple inheritance is a feature of object-oriented programming that allows a single class to inherit attributes and behavior from multiple parent classes. In this tutorial, we will learn about multiple inheritance in Python and how to use it efficiently.

Multiple inheritance is a powerful tool, but it can also make your code complex and hard to maintain if used incorrectly. Therefore, it is important to understand the basics of inheritance and the implications of multiple inheritance before you start using it in your projects.

What is inheritance in Python?

Inheritance is a mechanism that allows a class to inherit the attributes and behaviors of another class, called the parent class or the superclass. This is useful because it enables you to create new classes that are built on the foundation of existing classes, saving time and effort while avoiding duplication of code.

For example, suppose you have a class called “Animal” that defines the basic attributes and behaviors of all animals. You can then create a class called “Cat” that inherits from the “Animal” class and adds additional attributes and behaviors that are specific to cats.

In Python, inheritance is implemented using the class keyword. To inherit from a parent class, you simply specify the parent class in parentheses after the class name.

class Animal:
def __init__(self, name):
self.name = name


class Cat(Animal):
def meow(self):
print('Meow!')

In this example, the Cat class inherits from the Animal class. This means that instances of the Cat class have access to all of the attributes and behaviors defined in the Animal class, as well as any attributes and behaviors defined in the Cat class itself.

What is multiple inheritance in Python?

Multiple inheritance is a feature of object-oriented programming that allows a single class to inherit from multiple parent classes. This means that a single class can inherit attributes and behaviors from more than one parent class.

For example, suppose you have a class called Mammal that defines the basic attributes and behaviors of all mammals, and a class called “Felidae” that defines the attributes and behaviors of all felines. You can then create a class called Cat that inherits from both the Mammal and Felidae classes, inheriting attributes and behaviors from both parent classes.

In Python, multiple inheritance is implemented using the same syntax as single inheritance. To inherit from multiple parent classes, simply specify multiple parent classes in the parentheses after the class name, separated by commas.

class Mammal:
def __init__(self, name):
self.name = name


class Felidae:
def purr(self):
print('Purr...')


class Cat(Mammal, Felidae):
def meow(self):
print('Meow!')


loki = Cat('Loki')
loki.purr() # Purr...
loki.meow() # Meow!
print(loki.name) # Loki

In this example, the Cat class inherits from both the Mammal and Felidae classes. This means that instances of the Cat class have access to all of the attributes and behaviors defined in both parent classes, as well as any attributes and behaviors defined in the Cat class itself.

What if there are methods with the same name?

The example above works fine when there is no overlap between the method names in the parent class. Imagine if there was a method called say_hi that would be fined in both Mammal and Felidae. What would be the result of calling say_hi on the loki object? Which implementation would be executed? To answer that question let’s write the corresponding code:

class Mammal:
def __init__(self, name):
self.name = name

def say_hi(self):
print(f'{self.name}: Hi!')


class Felidae:
def __init__(self, name, color):
self.name = name
self.color = color

def purr(self):
print(f'{self.name}: Purr... (it had a {self.color} color)')

def say_hi(self):
print(f'{self.name}: Meow!')


class Cat(Mammal, Felidae):
def __init__(self, name, color):
Mammal.__init__(self, name)
Felidae.__init__(self, name, color)

def say_hi(self):
Felidae.say_hi(self)


loki = Cat('Loki', 'white')
loki.purr() # Loki: Purr... (it had a white color)
loki.say_hi() # Loki: Meow!
print(loki.name) # Loki

Here both Mammal and Felidae have a method called say_hi. So, the class Cat has to execute one of them. In this particular example, we have overridden the method say_hi to make sure it executes the one defined by Felidae. Yet, if we comment out that line of code, the Python interpreter would actually execute the method defined in the class Mammal. The reason is explained in the coming section.

The key takeaway here is that we can override the ambiguous methods to make them concrete and make sure that the code behaves as expected. We could’ve executed both base class methods in the implementation of say_hi as well, and we could’ve added some more functionality to it:

class Cat(Mammal, Felidae):
def __init__(self, name, color):
Mammal.__init__(self, name)
Felidae.__init__(self, name, color)

def say_hi(self):
Mammal.say_hi(self)
Felidae.say_hi(self)
print('That\'s all!')


loki = Cat('Loki', 'white')
loki.say_hi()
# Loki: Hi!
# Loki: Meow!
# That's all!

So, we have full control over how our classes behave when extending from multiple base classes.

How does multiple inheritance work in Python?

When multiple inheritance is used, Python follows a method resolution order (MRO) to determine the order in which parent classes are searched for attributes and behaviors. The MRO is determined using the C3 linearization algorithm, which is a complex algorithm that ensures that the MRO is consistent and prevents any circular dependencies in the inheritance hierarchy.

In the case of conflicts, where two or more parent classes define the same attribute or behavior, the first definition encountered by the MRO is used. This means that the order in which parent classes are specified in the class definition can be important when multiple inheritance is used.

It is important to note that Python does not support multiple inheritance of state, meaning that a class cannot inherit the same attribute from multiple parent classes. In the case of conflicting attributes, the last definition encountered by the MRO is used.

When to use multiple inheritance in Python?

Multiple inheritance is a powerful tool, but it should be used with caution. Because multiple inheritance can make your code complex and hard to maintain, it is important to use it only when necessary and to understand the implications of multiple inheritance before you start using it in your programs.

Multiple inheritance is best used when you need to create a class that can inherit attributes and behaviors from two or more parent classes that have a common interface. For example, if you have two classes that define similar behaviors, you can use multiple inheritance to create a new class that combines the behaviors of both parent classes.

What’s next?

--

--

Published in Dev Genius

Coding, Tutorials, News, UX, UI and much more related to development

Written by Martin Mirakyan

Software Engineer | Machine Learning | Founder of Profound Academy (https://profound.academy)

No responses yet