Inheritance in Python

Inheritance in Python

ยท

4 min read

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.

ย