Course Progress58%
🍎 Python OOP Topic 58 / 100
⏳ 8 min read

Method Overriding

Replace a parent class’s method with your own implementation in a child class — the foundation of polymorphism.

"Overriding is a child class saying: 'I inherited your method, but I know better how to do this for my specific case.'"

— ShurAI

What is Method Overriding?

When a child class defines a method with the same name as a method in the parent class, the child’s version replaces the parent’s version for that class. This is called overriding:

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

class Dog(Animal):
    def speak(self):              # overrides Animal.speak
        print("Woof!")

class Cat(Animal):
    def speak(self):              # overrides Animal.speak differently
        print("Meow!")

Animal().speak()   # Some animal sound
Dog().speak()      # Woof!
Cat().speak()      # Meow!

Polymorphism — One Interface, Many Behaviours

Because all three classes have a speak() method, you can call it on any of them through a shared loop — each responds in its own way. This is called polymorphism:

python
animals = [Dog(), Cat(), Dog(), Cat()]

for animal in animals:
    animal.speak()   # each object uses its own version

# Woof!
# Meow!
# Woof!
# Meow!
Without override
d = Dog()
d.speak()
# "Some animal sound"
# (uses parent's version)
With override
d = Dog()
d.speak()
# "Woof!"
# (uses Dog's version)

Extending the Parent Method

Use super().method() to run the parent version plus add your own logic:

python
class Shape:
    def describe(self):
        print("I am a shape.")

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def describe(self):
        super().describe()          # run parent first
        print(f"I am a circle with radius {self.radius}.")

Circle(5).describe()
# I am a shape.
# I am a circle with radius 5.

Real Example — Notification System

python
class Notification:
    def __init__(self, message):
        self.message = message

    def send(self):
        print(f"[Notification] {self.message}")

class EmailNotification(Notification):
    def __init__(self, message, to):
        super().__init__(message)
        self.to = to

    def send(self):            # overrides send()
        print(f"[Email to {self.to}] {self.message}")

class SMSNotification(Notification):
    def __init__(self, message, phone):
        super().__init__(message)
        self.phone = phone

    def send(self):            # overrides send() differently
        print(f"[SMS to {self.phone}] {self.message}")

alerts = [
    EmailNotification("Your order shipped!", "riya@mail.com"),
    SMSNotification("OTP: 4821",             "+91 98765"),
    Notification("System maintenance at 2AM"),
]
for alert in alerts:
    alert.send()
output
[Email to riya@mail.com] Your order shipped!
[SMS to +91 98765] OTP: 4821
[Notification] System maintenance at 2AM

"Polymorphism is what makes overriding powerful. Write for item in items: item.process() and each item does the right thing automatically, no matter what type it is."

— ShurAI

🧠 Quiz — Q1

What is method overriding?

🧠 Quiz — Q2

You have Dog inheriting from Animal. Both have a speak() method. When you call dog.speak(), which runs?

🧠 Quiz — Q3

What is polymorphism?

🧠 Quiz — Q4

You override describe() in a child but also want to run the parent's describe(). How?