Method overriding occurs when a subclass provides its own implementation of a method that already exists in its parent class. The overriding method has the same name and parameters as the parent version but executes different code, allowing objects of the subclass to behave differently without changing the original class.

Why is method overriding useful?

Consider a parent class Animal with a make_sound() method. A generic animal cannot produce a meaningful sound — but a Dog should bark and a Cat should meow. Method overriding lets each subclass customise inherited behaviour:

  • Animal.make_sound() might return an empty string or a placeholder.
  • Dog.make_sound() overrides this to return "Woof!".
  • Cat.make_sound() overrides this to return "Meow!".

The key benefit is that code written to call make_sound() on any Animal object will automatically get the correct sound for the actual type of animal — this is polymorphism in action. The calling code does not need to know whether it has a Dog or a Cat; it just calls the method and trusts the object to respond correctly.

How do you override a method in Python?

To override a method in Python, simply define a method with the same name in the subclass. Python automatically uses the subclass version when the method is called on a subclass object.

class Animal:
    def __init__(self, name):
        self.__name = name
    
    def get_name(self):
        return self.__name
    
    def make_sound(self):
        return "..."  # generic placeholder

class Dog(Animal):
    def make_sound(self):  # overrides Animal.make_sound()
        return "Woof!"

class Cat(Animal):
    def make_sound(self):  # overrides Animal.make_sound()
        return "Meow!"

Calling make_sound() on a Dog object returns "Woof!" even though Dog inherits from Animal — Python looks in the subclass first.

rex = Dog("Rex")
luna = Cat("Luna")
print(rex.make_sound())   # Output: Woof!
print(luna.make_sound())  # Output: Meow!

How does Python decide which method to run?

Python uses the Method Resolution Order (MRO): when a method is called, Python searches the class hierarchy starting with the class of the actual object, then moves up to parent classes. The first matching method found is the one that runs.

Object type Method called Where Python looks first Result
Dog make_sound() Dog class "Woof!" (found — stops here)
Cat make_sound() Cat class "Meow!" (found — stops here)
Animal make_sound() Animal class "..." (found — stops here)

This search order means a subclass method always takes priority over a parent class method with the same name.

How do you call the parent's version of a method using super()?

Sometimes a subclass wants to extend a method rather than completely replace it — running the parent's code first and then adding extra behaviour. The super() function gives access to the parent class:

class Vehicle:
    def describe(self):
        return "I am a vehicle."

class Car(Vehicle):
    def describe(self):
        parent_description = super().describe()  # calls Vehicle.describe()
        return parent_description + " Specifically, I am a car."

my_car = Car()
print(my_car.describe())
# Output: I am a vehicle. Specifically, I am a car.

super().describe() calls the parent's describe() method and returns its result, which Car.describe() then appends to. Without super(), the parent's logic would be lost entirely. You also see this pattern in __init__ when a subclass constructor needs to initialise the parent's attributes:

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)    # run Animal's __init__
        self.__breed = breed      # then add Dog's own attribute

How does overriding relate to polymorphism?

Method overriding is the mechanism that makes polymorphism work. If you store different types of objects in a list and call the same method on each, overriding ensures each object responds with its own behaviour:

animals = [Dog("Rex"), Cat("Luna"), Dog("Fido")]
for animal in animals:
    print(animal.get_name(), "says", animal.make_sound())
# Rex says Woof!
# Luna says Meow!
# Fido says Woof!

The loop does not care whether each element is a Dog or a Cat — it calls make_sound() on whatever object it finds, and overriding guarantees the correct sound is produced. This pattern makes programs flexible and extensible: adding a new animal type (e.g., Bird) only requires creating a new class with its own make_sound() override, without changing any existing code.

Frequently asked questions

Is method overriding the same as method overloading?

No. Method overriding happens across a parent–subclass relationship: the subclass redefines a method it inherits, replacing the parent's version. Method overloading means having multiple methods with the same name but different parameter lists within the same class. Python does not support traditional method overloading — the last definition wins — but you can simulate it using default parameter values or *args.

Do you need a special keyword to override in Python?

No. Simply defining a method with the same name in a subclass is enough. Unlike Java (which uses @Override as an optional annotation) or C++ (which requires the virtual keyword in the parent), Python uses duck typing and the MRO to resolve which method runs at call time.

What happens if you forget to override an abstract method?

If a parent class has an abstract method (marked with @abstractmethod from the abc module), any subclass that does not override it cannot be instantiated — Python raises a TypeError. This enforces a contract: every concrete subclass guarantees it provides its own implementation of the abstract method. This is how abstract classes ensure subclasses are complete.

Can overriding break existing code?

If the overriding method changes the behaviour expected by code that calls the parent class interface, it can introduce bugs. The Liskov Substitution Principle (an important OOP design rule) states that objects of a subclass should be usable wherever the parent class is expected, without breaking correctness. A Dog should be able to do everything an Animal can, just with more specific behaviour — not fewer or contradictory behaviours.


Build OOP fluency with Professor Turing at aitutors.me, working through inheritance and overriding interactively.