Method Overriding in Python

Method Overriding in Python is an object-oriented programming concept where a child class provides a specific implementation of a method that is already defined in its parent class. This allows the subclass to modify or extend the behavior of the inherited method without changing the parent class.

How Method Overriding Works

When a method in the child class has the same name as a method in the parent class, the method in the child class overrides the parent method. This means that when the method is called on an instance of the child class, the child’s version of the method is executed instead of the parent’s version.

Examples

1. Basic Method Overriding

In this example, we define a base class Animal with a method make_sound(). The derived class Dog overrides this method to provide its own implementation.

</>
Copy
# Defining the parent class
class Animal:
    def make_sound(self):
        return "Some generic animal sound"

# Defining the child class that overrides the method
class Dog(Animal):
    def make_sound(self):
        return "Bark"

# Creating instances
animal = Animal()
dog = Dog()

# Calling the method
print("Animal makes:", animal.make_sound())  # Calls parent method
print("Dog makes:", dog.make_sound())        # Calls overridden method

Output:

Animal makes: Some generic animal sound
Dog makes: Bark

Here, the method make_sound() in the Dog class overrides the method from the Animal class. When we call make_sound() on an instance of Dog, it executes the overridden method, returning “Bark”.

2. Calling the Parent Method Using super()

Sometimes, we might want to use the parent class’s method inside the overridden method. This can be done using super().

</>
Copy
# Defining the parent class
class Animal:
    def make_sound(self):
        return "Some generic animal sound"

# Defining the child class with method overriding using super()
class Dog(Animal):
    def make_sound(self):
        parent_sound = super().make_sound()  # Calls the parent method
        return parent_sound + " and also Barks"

# Creating instance of Dog
dog = Dog()

# Calling the method
print("Dog makes:", dog.make_sound())

Output:

Dog makes: Some generic animal sound and also Barks

Here, the child class Dog overrides make_sound() but still calls the parent class’s method using super(). This way, it retains the behavior of the parent method while extending it.

3. Overriding with Additional Parameters

We can also override methods while changing their parameters to make them more specific for the child class.

</>
Copy
# Defining the parent class
class Animal:
    def make_sound(self):
        return "Some generic animal sound"

# Defining the child class with an overridden method that accepts a parameter
class Cat(Animal):
    def make_sound(self, times=1):
        return "Meow " * times

# Creating instances
cat = Cat()

# Calling the method with different arguments
print(cat.make_sound())       # Default call
print(cat.make_sound(3))      # Overridden method with parameter

Output:

Meow 
Meow Meow Meow 

In this example, the Cat class overrides make_sound() to accept an optional parameter times, which determines how many times “Meow” should be repeated.

4. Handling Errors in Method Overriding

If a child class overrides a method incorrectly (for example, forgetting required parameters), it can lead to errors. Let’s see an example of an incorrect override and how to fix it.

</>
Copy
# Defining the parent class
class Animal:
    def make_sound(self, sound):
        return f"Animal makes {sound}"

# Incorrect method override (missing the 'sound' parameter)
class Bird(Animal):
    def make_sound(self):
        return "Chirp"

# Creating instances
try:
    bird = Bird()
    print(bird.make_sound("Tweet"))
except TypeError as e:
    print("Error:", e)

Output:

Error: make_sound() takes 1 positional argument but 2 were given

Since the parent class requires a parameter sound, but the child class override does not include it, a TypeError occurs. To fix this, we must match the signature correctly:

</>
Copy
# Defining the parent class
class Animal:
    def make_sound(self, sound):
        return f"Animal makes {sound}"

# Correcting the override
class Bird(Animal):
    def make_sound(self, sound):
        return f"Bird makes {sound}"

# Creating instance and calling method correctly
bird = Bird()
print(bird.make_sound("Tweet"))

Output:

Bird makes Tweet

Now, the child class correctly overrides the method with the required parameter.