Some programming languages, such as Python, C++, etc, allow classes to inherit multiple other classes (i.e. allow multiple inheritance).
Hence, when we inherit multiple classes from another, different types of inheritance patterns can be formed.
However, one pattern of inheritance in programming languages that resembles a diamond shape cause ambiguity in the call to the parent class method, which is popularly known as the diamond problem.
In this tutorial, we will learn what actually the diamond problem is and how can we resolve it in Python.
What is Diamond Problem?
The diamond problem occurs when two classes have a common parent class, and another class has both those classes as base classes.
IIn this kind of implementation of inheritance, if class B
and class C
override (any) same method of class A
and instance of class D
calls that method, it becomes ambiguous to programming languages, whether we want to call the overridden method from class B
or the one from class C
.
For example:
class A:
def display(self):
print("This is class A")
class B(A):
def display(self):
print("This is class B")
class C(A):
def display(self):
print("This is class C")
class D(B, C):
pass
obj = D()
obj.display()
In this code example, we are calling display
method on the instance of class D
. As class D
inherits both class B
and class C
, it is unknown which of the overridden display
will be called by Python interpreter.
How to Solve Diamond Problem in Python?
Because of the method resolution order (__mro__
) in Python, the ambiguity of the diamond problem in Python becomes irrelevant.
The method resolution order in Python is the order in which a method is searched for in the class hierarchy, in case of inheritance.
We can view this order by accessing the __mro__
attribute on the classes.
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
As we can see, in the __mro__
output of class D
, the class B
comes before class C
. Therefore, if call the display
method on class D
the Python interpreter will find and invoke the display
method of class B
.
>>> obj.display()
This is class B
When we inherit from multiple classes, and if their method name conflicts, then the first-class name takes precedence. This is the reason why, class B
is before class C
in the order of __mro__
.