11. Multiple Inheritance
By Bernd Klein. Last modified: 24 Mar 2024.
Introduction
In the previous chapter of our tutorial, we have covered inheritance, or more specific "single inheritance". As we have seen, a class inherits in this case from one class. Multiple inheritance on the other hand is a feature in which a class can inherit attributes and methods from more than one parent class. The critics point out that multiple inheritance comes along with a high level of complexity and ambiguity in situations such as the diamond problem. We will address this problem later in this chapter.
The widespread prejudice that multiple inheritance is something "dangerous" or "bad" is mostly nourished by programming languages with poorly implemented multiple inheritance mechanisms and above all by improper usage of it. Java doesn't even support multiple inheritance, while C++ supports it. Python has a sophisticated and well-designed approach to multiple inheritance.
A class definition, where a child class SubClassName inherits from the parent classes BaseClass1, BaseClass2, BaseClass3, and so on, looks like this:
class SubclassName(BaseClass1, BaseClass2, BaseClass3, ...):
pass
It's clear that all the superclasses BaseClass1, BaseClass2, BaseClass3, ... can inherit from other superclasses as well. What we get is an inheritance tree.

Live Python training
See our Python training courses
Example: CalendarClock
We want to introduce the principles of multiple inheritance with an example. For this purpose, we will implement to independent classes: a "Clock" and a "Calendar" class. After this, we will introduce a class "CalendarClock", which is, as the name implies, a combination of "Clock" and "Calendar". CalendarClock inherits both from "Clock" and "Calendar".

The class Clock simulates the tick-tack of a clock. An instance of this class contains the time, which is stored in the attributes self.hours, self.minutes and self.seconds. Principally, we could have written the __init__ method and the set method like this:
def __init__(self,hours=0, minutes=0, seconds=0):
self._hours = hours
self.__minutes = minutes
self.__seconds = seconds
def set(self,hours, minutes, seconds=0):
self._hours = hours
self.__minutes = minutes
self.__seconds = seconds
We decided against this implementation, because we added additional code for checking the plausibility of the time data into the set method. We call the set method from the __init__ method as well, because we want to circumvent redundant code.
The complete Clock class:
"""
The class Clock is used to simulate a clock.
"""
class Clock(object):
def __init__(self, hours, minutes, seconds):
"""
The paramaters hours, minutes and seconds have to be
integers and must satisfy the following equations:
0 <= h < 24
0 <= m < 60
0 <= s < 60
"""
self.set_Clock(hours, minutes, seconds)
def set_Clock(self, hours, minutes, seconds):
"""
The parameters hours, minutes and seconds have to be
integers and must satisfy the following equations:
0 <= h < 24
0 <= m < 60
0 <= s < 60
"""
if type(hours) == int and 0 <= hours and hours < 24:
self._hours = hours
else:
raise TypeError("Hours have to be integers between 0 and 23!")
if