Python

Inheritance

YouTube

In object-oriented programming (OOP), inheritance is a powerful concept that empowers developers to create organised and reusable code structures. Python, as a versatile and widely-used programming language, excels in implementing inheritance, allowing developers to build hierarchies of related classes that share attributes and behaviours. In this article, we will explore the fundamentals of inheritance in Python, its benefits, and how it enhances code modularity and efficiency.

The Essence of Inheritance

Inheritance is a fundamental pillar of OOP that enables developers to create new classes based on existing ones. This mechanism promotes code reuse and facilitates the creation of well-organised class hierarchies. Python’s inheritance model is dynamic, flexible, and aligned with its philosophy of “readable and beautiful code.”

The Superclass-Subclass Relationship

At the heart of inheritance lies the concept of a superclass (also known as a parent class) and a subclass (or child class). The subclass inherits attributes and methods from its superclass, allowing developers to extend and specialise the behaviour of existing classes.

class Animal:
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        return "Woof!"

class Cat(Animal):
    def speak(self):
        return "Meow!"
Benefits of Inheritance
  • Inheritance allows you to create a common base class with shared attributes and methods that can be inherited by multiple subclasses. This avoids code duplication and promotes modular design.
  • By organising related classes into a hierarchy, you enhance code modularity. Changes made in the superclass propagate to all subclasses, promoting easier maintenance and updates.
  • Subclasses can inherit attributes and methods from the superclass while adding their own unique attributes and behaviours. This specialisation allows you to create more specific classes without reinventing the wheel.
Inheriting Attributes and Methods:

In Python, subclasses inherit attributes and methods from the superclass automatically. When a method is called on a subclass object, Python searches for the method in the subclass first, and then in the superclass.

Overriding and Extending Methods:

Subclasses can modify the behaviour of inherited methods by providing their own implementation. This process is called method overriding. Additionally, subclasses can extend inherited methods by adding new functionality while retaining the superclass’s behaviour.

class Bird(Animal):
    def speak(self):
        return "Chirp!"

class Parrot(Bird):
    def speak(self):
        return "Squawk!"
The super() Function:

The super() function allows subclasses to access methods and attributes of the superclass. It’s used to call superclass methods explicitly, enabling fine-grained control over method execution.

Multiple Inheritance:

Python supports multiple inheritance, allowing a subclass to inherit from multiple superclasses. While powerful, multiple inheritance requires careful design to avoid potential complications known as the “diamond problem.”

Abstract Base Classes (ABCs):

Python provides a mechanism for creating abstract base classes using the abc module. Abstract base classes define a common interface for subclasses to adhere to, ensuring a specific set of methods are implemented.

Polymorphism and Inheritance:

Inheritance works seamlessly with polymorphism, enabling objects of different classes to be treated uniformly when they share a common superclass.

Inheritance is a foundational concept in Python’s object-oriented paradigm that promotes code reusability, modularity, and specialisation. By leveraging inheritance, developers can build organised class hierarchies that enhance code efficiency and maintainability. Python’s dynamic and flexible inheritance model empowers developers to create elegant solutions for a wide range of software design challenges, making it a cornerstone of modern programming practices.

Let’s look at the previous page’s code for the class Vehicle, and we will create two classes that inherit from the Vehicle class. The first will be a car, the second will be a lorry. Hopefully, now you will start to understand that having a base class allows us to customise one subclass more than another in specific ways, while them still having the same blueprint design.

class Vehicle:
    def __init__(self, model, make, year):
        self.model = model
        self.make = make
        self.year = year
        self.speed = 0
        
    def move(self):
        if self.year > 1970:
            self.speed += 30
            print("You are going 30mph!")
            
    def slow_down(self):
        if self.speed >= 1:
            self.speed -= 5


class Car(Vehicle):
    def __init__(self, model, make, year):
        super().__init__(model, make, year)
        
class Lorry(Vehicle):
    def __init__(self, model, make, year):
        super().__init__(model, make, year)
    
car = Car("1 Series", "BMW", 2011)
lorry = Lorry("Big Lorry", "Volkswagen", 2020)
car.move()
lorry.move()