Lecture-46 (Multiple, Hybrid Inheritance)
Lecture-46 (Multiple, Hybrid Inheritance)
Lecture-46 (Multiple, Hybrid Inheritance)
LECTURE 46
Today’s Agenda
• Multiple Inheritance
• The MRO Algorithm
• Hybrid Inheritance
• The Diamond Problem
Multiple Inheritance
class A:
# properties of class A
class B:
#properties of class B
class C(A,B):
# class C inheriting property of class A
# class C inheriting property of class B
# more properties of class C
Example
class A:
Output:
def m(self):
print("m of A called")
Why did m( ) of A
class B: got called ?
def m(self):
print("m of B called") This is because of a
special rule in
Python called MRO
class C(A,B):
pass
obj=C()
obj.m()
What Is MRO In Python ?
MRO RULE :
In the multiple inheritance scenario, any specified attribute is searched
first in the current class. If not found, the search continues into
parent classes, left-right fashion and then in depth-first
without searching same class twice.
Can We See This MRO ?
class A:
def m(self):
print("m of A called")
class B:
def m(self):
print("m of B called")
class C(A,B):
pass
print(C.mro())
Output
Another Way To See MRO ?
class A:
def m(self):
print("m of A called")
class B:
def m(self):
print("m of B called")
class C(A,B):
pass
print(C.__mro__)
Output
The Hybrid Inheritance
class A: obj=D()
def m1(self): obj.m1()
print("m1 of A called") obj.m2()
class B(A): obj.m3()
def m2(self):
print("m2 of B called")
class C(A):
def m3(self):
print("m3 of C called")
class D(B,C):
pass
Output:
The Diamond Problem
class A:
obj=D()
def m(self):
obj.m()
print("m of A called")
class B(A):
Why m() of B was called ?
def m(self):
As discussed previously , Python
print("m of B called")
uses MRO to search for an
attribute which goes from left to
class C(A): right and then in depth first.
def m(self): Now since B is the first
print("m of C called") inherited class of D so Python
called m( ) of B
class D(B,C):
pass
Output:
Guess The Output
class A:
obj=D()
def m(self):
obj.m()
print("m of A called")
class B(A):
def m(self):
print("m of B called")
class C(A):
def m(self):
print("m of C called")
class D(C,B):
pass
Output:
Guess The Output
class A:
obj=D()
def m(self): obj.m()
print("m of A called")
Why m() of C was called ?
class B(A):
pass MRO goes from left to right first
and then depth first. In our case
Python will look for method m()
class C(A): in B but it won’t find it there .
def m(self): Then it will search m() in C
print("m of C called") before going to A. Since it finds
m() in C, it executes it dropping
the further search
class D(B,C):
pass
Output:
Guess The Output
class A:
obj=D()
def m(self):
print("m of A called")
obj.m()
class B(A):
def m(self):
print("m of B called")
class C(A):
def m(self):
print("m of C called")
class D(B,C):
def m(self):
print("m of D called")
Output:
Guess The Output
class A:
def m(self): obj=D()
print("m of A called") obj.m()
class B(A):
def m(self):
print("m of B called")
class C(A):
def m(self):
print("m of C called")
class D(B,C):
def m(self):
print("m of D called")
B.m(self)
C.m(self)
A.m(self)
Output:
Guess The Output
class A:
def m(self): obj=D()
print("m of A called") obj.m()
class B(A):
def m(self):
print("m of B called") Why m() of A was called
A.m(self)
class C(A):
twice?
def m(self): This is because we have
print("m of C called") called A.m(self) in both B
A.m(self)
class D(B,C):
and C classes due to which
def m(self): the method m() of A gets
print("m of D called") called 2 times
B.m(self)
C.m(self)
Output:
Using super( ) To Solve
The Previous Problem
class A:
def m(self): obj=D()
print("m of A called") obj.m()
class B(A):
def m(self):
print("m of B called")
super().m()
class C(A):
def m(self):
print("m of C called")
super().m()
class D(B,C):
def m(self):
print("m of D called")
super().m()
Output: