Back to: Python Programming
Multiple and Multi-level Inheritance allows a child class to inherit from more than one parent class.
multiple inheritance = inherit from more than one parent class.
multi-level inheritance = inherit from a parent which inherits from another parent.
multiple inheritance
Let’s create two parent classes:
class Prey: # <-- Parent class
def flee(self):
print("This animal is fleeing")
class Predator: # <-- Parent class
def hunt(self):
print("This animal is hunting")
class Rabbit(Prey): # <-- Child class
pass
class Hawk(Predator): # <-- Child class
pass
class Fish(Prey, Predator): # <-- Child class inheriting from BOTH parent classes
pass
rabbit = Rabbit()
hawk = Hawk()
fish = Fish()
rabbit.flee()
The last line:
“rabbit.flee()” will output “This animal is fleeing” because it inherits this attribute from the Prey class.
Change it to:
“rabbit.hunt()” will output an AttributeError: ‘Rabbit’ object has no attribute ‘hunt’.
However:
“fish.flee()” will output “This animal is fleeing” because it inherits this attribute from the Prey class
AND
“fish.hunt()” will output “This animal is hunting” because it ALSO inherits this attribute from the Predator class.
Try it!
Multi-Level Inheritance
With multi-level inheritance, a parent can inherit from another parent. We’ll create a new class called Animal – we can think along the lines that Animal is the Grandparent to Prey and Predator, which are parents to Rabbit, Hawk and Fish:
class Animal: # <-- Grandparent class
def eat(self):
print("This animal is eating")
def sleep(self):
print("This animal is sleeping")
class Prey(Animal):
def flee(self):
print("This animal is fleeing")
class Predator(Animal):
def hunt(self):
print("This animal is hunting")
class Rabbit(Prey):
pass
class Hawk(Predator):
pass
class Fish(Prey, Predator):
pass
rabbit = Rabbit()
hawk = Hawk()
fish = Fish()
rabbit.eat()
hawk.sleep()
fish.hunt()
Outputs:
This animal is eating
This animal is sleeping
This animal is hunting
Expanding on this example, we will name our objects. Within our classes we don’t have any constructor set up.
In which class should we assign the name attribute?
Let’s do so within the Animal class. We will define a constructor to assign these attributes. We will receive a name and assign self.name = name.
With the other classes, if you are NOT assigning any attributes, or if you don’t need any other initialisation logic, you don’t need a constructor. We’ll implicitly use the constructor we inherit from the parent.
Finally, we can now convert each print statement to an f-string to use their names.
class Animal:
def __init__(self, name):
self.name = name
def eat(self):
print(f"{self.name} is eating")
def sleep(self):
print(f"{self.name} is sleeping")
class Prey(Animal):
def flee(self):
print(f"{self.name} is fleeing")
class Predator(Animal):
def hunt(self):
print(f"{self.name} is hunting")
class Rabbit(Prey):
pass
class Hawk(Predator):
pass
class Fish(Prey, Predator):
pass
rabbit = Rabbit("Bugs")
hawk = Hawk("Tony")
fish = Fish("Nemo")
fish.eat() # <-- Our fish use the eat method
fish.flee() # <-- our fish can use the flee method
fish.hunt() # <-- our fish can use the hunt method
hawk.hunt() # <-- our hawk can use the hunt method
rabbit.flee() # <-- our rabbit can use the flee method
Output:
Nemo is eating
Nemo is fleeing
Nemo is hunting
Tony is hunting
Bugs is fleeing