Inheritance in Object Oriented Programming in Python
By inheritance we can use facilities of base class while adding more functionality to derived class . This helps in reusability of code and easy maintenance.
Video Tutorial on OOPs. Part - 2
Base or parent class : Our main class where methods and properties are declared. Derived or child class: Can use methods and properties of Base class along with its own functionality.
class x(): # base or parent class
def x_one(self):
print("I am x_one")
class y(x):# derived or child class
def y_one(self):
print("I am y_one")
y1=y() # object declaration of class y()
y1.x_one()
Output
I am x_one
multilevel inheritance
There can be multiple level of derived or child classes. One parent class ( y here ) can be the child of another class ( x here ). Class x is the base class of y and y is the base class of z.
X > Y > Z
With this multilevel of inheritance the object of z can use method of class x.
class x():
def x_one(self):
print("I am x_one")
class y(x):
def y_one(self):
print("I am y_one")
class z(y):
def z_one(self):
print("I am z_one")
z1=z() # object of z class
z1.x_one()
z1.y_one()
z1.z_one()
Output
I am x_one
I am y_one
I am z_one
multiple inheritance
One child class ( z here ) can have multiple parent or base class ( y and x here ). Note that y is not the child class of x but z is the child class of x and y. So z can use methods of both x and y, but y can't use methods of x.
class x():
def x_one(self):
print("I am x_one")
class y():
def y_one(self):
print("I am y_one")
class z(x,y): # z is child of x and y
def z_one(self):
print("I am z_one")
z1=z()
z1.x_one()
z1.y_one()
z1.z_one()
Output
I am x_one
I am y_one
I am z_one
Child class with __init__()
Note that we have not used method __init__() in our child class. Since child class has inherited the __init__() method of parent class so we continue to use the same. We can also use __init__() in our child class. But this constructor of __init__() in child class will disconnect the inheritance of constructor from parent class.
Method Resolution Order ( MRO )
Video Tutorial on OOPs. Part - 3
We are using inheritance where object can use methods of different classes. We may have common methods in different classes, then how Python will decide which order to follow the reach the desired method?
Here is an example of how Method resolution Order decide the method to use.
class x(): # base or parent class
def m1(self):
print("I am x m1")
class y(x):# derived or child class
def m1(self):
print("I am y m1") # this will execute
y1=y()
y1.m1()
Output
I am y m1
MRO with multiple inheritance
class x(): # base or parent class
def m1(self):
print("I am x m1")
class y():
def m1(self):
print("I am y m1")
class z(x,y): # multiple inheritance
pass
z1=z() # object of z()
z1.m1() # method with class x() will be executed
Output
I am x m1
In above code change the class declaration of z like this.
class z(y,x): # multiple inheritance
Now check the output
I am y m1
We can use mro() method to check the mro of the class.
We have two class here, one is base or parent class animal() and another one is derived or child class wild(). We are creating an object tiger of class wild(). You can see the attributes name and height belongs to parent class animal() whereas weight belongs to child class wild().
Since wild() is a object of derived class wild(), we have used inheritance to use parent class attributes name and height along with the weight and displayed the values.
class animals():
home='Jungle' #class attribute
#instance attributes
def __init__(self,name,height):
self.name= name
self.height=height
class wild(animals):
weight=2
tiger=wild('Tom',3) # object is created.
print(tiger.name, tiger.height,tiger.weight,tiger.home,sep=',')
Output
Tom,3,2,Jungle
Using Base class
We will create an object of base class animals()
lion=animals('Alex',5) # object
print(lion.name) # Alex
print(lion.weight) # error
The last line will generate error as weight is not an attribute of base class animal() ( it is attribute of child class wild() )
The last line print(tiger.height) in below code will generate error as we have not inherited the base __init__() method.
class animals():
#instance attributes
def __init__(self,name,height):
self.name= name
self.height=height
def legs(self):
print("has four legs")
class wild(animals):
def __init__(self,name,weight):
self.name=name
self.weight=weight
tiger=wild('Tom',3) # object is created.
print(tiger.weight)
print(tiger.height) # Error
To use the base class methods we will add this line animals.__init__(self,name,5) to our __init__() in child class.
class animals():
home='Jungle' #class attribute
#instance attributes
def __init__(self,name,height):
self.name= name
self.height=height
def legs(self):
print("has four legs")
class wild(animals):
def __init__(self,name,weight):
self.name=name
self.weight=weight
animals.__init__(self,name,5)
tiger=wild('Tom',3) # object is created.
print(tiger.weight) # 3
print(tiger.height) # 5
super()
In above code we have used the name of our base class animals() to inherit the constructor.
animals.__init__(self,name,5)
We need not explicitly declare the base class and just use super() function in python to use all the methods of base class. This is a big advantage while using multiple inheritance. Here is the example of linking base class by using super().
super().__init__(name,5)
The full code is here
class animals():
home='Jungle' #class attribute
#instance attributes
def __init__(self,name,height):
self.name= name
self.height=height
def legs(self):
print("has four legs")
class wild(animals):
def __init__(self,name,weight):
self.name=name
self.weight=weight
#animals.__init__(self,name,5)
super().__init__(name,5)
tiger=wild('Tom',3) # object is created.
print(tiger.weight) # 3
print(tiger.height) # 5
tiger.legs()
Using isinstance()
By using isinstance() we can check if the object is instance of the class or not. Here we will check if the object tiger is instance of animals() or not. Use this line at the end of above code.