Inheritance is a fundamental concept in object-oriented programming that allows you to create new classes based on existing classes, enabling code reuse and promoting a hierarchical structure.
Single Inheritance:
Single inheritance refers to a scenario where a class inherits from a single base class.
The derived class acquires the attributes and methods of the base class, allowing for code reuse and extension of functionality.
class Creatures:
def character(self):
print("They Cannot talk")
class Bird(Creatures):
def feature(self):
print("Bird Can Fly")
# Creating an instance of Dog
bird = Bird()
bird.feature() # Output: Bird Fly
bird.character() # Output: They Cannot talk
In this example, the Bird
class inherits from the Creatures
class using single inheritance. So, I can easily use the properties of the Creatures class inside the Bird class. For instance, bird. character()
in the above example.
Multilevel Inheritance
Multilevel inheritance involves a chain of inheritance where a derived class inherits from a base class, and another class inherits from the derived class.
class Vehicle:
def drive(self):
print("Help in Driving")
class Car(Vehicle):
def __init__(self, color, speed):
self.color = color
self.speed = speed
def feature(self):
print(f"Its color is {self.color} and speed is{self.speed}")
class SportsCar(Car):
def __init__(self, color, speed, price):
super().__init__(color, speed)# overriding init method of Car
self.price = price
car = Car('black','100km/hr')
sport_car = SportsCar('red','200km/hr','15000$')
car.drive()
sport_car.feature() # accessing Car method
sport_car.drive() #accessing Vehicle method
Output :
Help in Driving
Its color is red and speed is200km/hr
Help in Driving
In this example, the SportsCar
class inherits from theCar
class, which itself inherits from the Vehicle
class. The SportsCar
class inherits the drive
method from the Vehicle
class through the intermediate Car
class.
super() keyword
super()
is a built-in function that allows you to call a method from a parent class within a subclass.It provides a convenient way to invoke the parent class's methods and access its attributes.
In the above example of multilevel inheritance, I am using super().__init__(color, speed) in the class SportsCar to override attributes from Car class.
class SportsCar(Car): def __init__(self, color, speed, price): super().__init__(color, speed)#overriding init method of Car self.price = price '''THIS CODE IS EQUIVALENT TO BELOW CODE''' class SportsCar(Car): def __init__(self, color, speed, price): self.color = color self.speed = speed self.price = price
Multiple Inheritance
Multiple inheritance allows a class to inherit from more than one base class.
The derived class inherits attributes and methods from all the base classes, enabling it to combine the properties and behaviors of multiple classes. Let's explore an example:
class Vehicle:
def drive(self):
print("Driving")
class Car:
def __init__(self, color, speed):
self.color = color
self.speed = speed
def feature(self):
print(f"It color is {self.color} and speed is{self.speed}")
class SportsCar(Vehicle, Car):
def __init__(self, color, speed, price):
super().__init__(color, speed)#overriding attribute of Car class
self.price = price
car = Car('black','100km/hr')
sport_car = SportsCar('red','200km/hr','15000$')
sport_car.drive() # Output: Driving
In this example, the Duck
class inherits from both the Flyer
and Swimmer
classes using multiple inheritances. The Duck
class can access the methods of both base classes.
MRO algorithm
MRO (Method Resolution Order) is a process in Python that determines the order in which methods are resolved or searched for in a class hierarchy.
It is used when multiple inheritance is involved, and it helps avoid ambiguities and conflicts in method resolution.
class A: def greet(self): print("Hello from A") class B(A): def greet(self): print("Hello from B") class C(A): def greet(self): print("Hello from C") class D(B, C): pass # Creating an instance of D d = D() d.greet() print(d.greet()) print(D.mro())
Output :
Hello from B [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
If we want to access the greet() method making an object for D then first it will check it in class D and then similarly in class B, C, and A respectively according to
mro
algorithm as in the above example.We are sure that we are creating the object of class D.So, it first checks in class D. But between class B and class C, class B is on the left of class C. Therefore, it accesses the method from class B based on
mro()
algorithm.