Inheritance in Python

basic
Published

April 10, 2024

Inheritance is a powerful mechanism in object-oriented programming (OOP) that allows you to create new classes (child classes or subclasses) based on existing classes (parent classes or superclasses). This promotes code reusability, reduces redundancy, and enhances the organization of your code. This post will look into inheritance in Python, providing clear explanations and practical examples.

Understanding the Core Concepts

Inheritance establishes an “is-a” relationship between classes. For instance, if you have a Dog class and a GoldenRetriever class, you can say a GoldenRetriever “is a” Dog. The GoldenRetriever class inherits attributes and methods from the Dog class, and can also define its own unique attributes and methods.

This relationship is visually represented as a hierarchy, with parent classes at the top and child classes branching down.

Implementing Inheritance in Python

In Python, inheritance is straightforward. You specify the parent class in parentheses after the child class definition:

class Dog:
    def __init__(self, name, breed):
        self.name = name
        self.breed = breed

    def bark(self):
        print("Woof!")

class GoldenRetriever(Dog):
    def fetch(self):
        print("Fetching!")

my_dog = Dog("Buddy", "Labrador")
my_golden = GoldenRetriever("Max", "Golden Retriever")

my_dog.bark()  # Output: Woof!
my_golden.bark() # Output: Woof! (inherited from Dog)
my_golden.fetch() # Output: Fetching!

In this example, GoldenRetriever inherits the __init__ method (constructor) and bark method from Dog. It then adds its own fetch method.

Method Overriding

Child classes can override methods inherited from the parent class. This allows you to provide a specific implementation for a method that’s already defined in the parent class.

class Animal:
    def speak(self):
        print("Generic animal sound")

class Cat(Animal):
    def speak(self):
        print("Meow!")

my_animal = Animal()
my_cat = Cat()

my_animal.speak() # Output: Generic animal sound
my_cat.speak() # Output: Meow!

Here, Cat overrides the speak method of Animal.

Multiple Inheritance

Python supports multiple inheritance, meaning a child class can inherit from multiple parent classes.

class Flyer:
    def fly(self):
        print("Flying!")

class Swimmer:
    def swim(self):
        print("Swimming!")

class FlyingFish(Flyer, Swimmer):
    pass

my_fish = FlyingFish()
my_fish.fly() # Output: Flying!
my_fish.swim() # Output: Swimming!

FlyingFish inherits both fly from Flyer and swim from Swimmer.

The super() Function

The super() function is important when working with inheritance, especially when you want to extend or modify methods from parent classes without completely rewriting them.

class Bird:
    def __init__(self, name):
        self.name = name

    def intro(self):
        print(f"I'm a bird named {self.name}")

class Parrot(Bird):
    def __init__(self, name, color):
        super().__init__(name) # Calls the Bird's __init__ method
        self.color = color
    def intro(self):
        super().intro() # Calls the Bird's intro method
        print(f"And I'm {self.color}!")

my_parrot = Parrot("Polly", "Green")
my_parrot.intro()

super() ensures that the parent class’s methods are called correctly, maintaining a clear and organized inheritance structure.

Inheritance and Polymorphism

Inheritance plays a significant role in achieving polymorphism, a fundamental concept in OOP. Polymorphism allows objects of different classes to respond to the same method call in their own specific way. We already saw this with the speak() method example earlier. This flexibility is a key benefit of using inheritance effectively.