Python
Method Overriding
Object-Oriented Programming
Python Decorators
Inheritance

In Python, how do I indicate I'm overriding a method?

Object-Oriented Design practice on Codemia

Turn requirements into classes, and defend the design, on the problems that come up in OOD rounds.

Practice OOD

Introduction

In Python, overriding a method does not require a special keyword, because a subclass simply defines a method with the same name. If you want to indicate intent explicitly, the modern answer is to use an @override decorator for readability and static checking rather than for runtime necessity.

Python does not require a keyword

Basic overriding works without any extra syntax:

python
1class Animal:
2    def speak(self) -> str:
3        return "generic sound"
4
5
6class Dog(Animal):
7    def speak(self) -> str:
8        return "woof"
9
10
11print(Dog().speak())

That is already a valid override. Python relies on method name lookup and inheritance rather than a mandatory language keyword.

Use @override when you want explicit intent

In modern Python, you can mark an overriding method with typing.override in Python 3.12 and newer.

python
1from typing import override
2
3
4class Animal:
5    def speak(self) -> str:
6        return "generic sound"
7
8
9class Dog(Animal):
10    @override
11    def speak(self) -> str:
12        return "woof"

The decorator does not change dispatch behavior. Its purpose is to express intent and help static type checkers catch mistakes such as misspelled method names.

For older Python versions, use typing_extensions:

python
from typing_extensions import override

Why @override is useful

Suppose you intend to override speak, but accidentally type speek. Without an explicit override marker, Python simply creates a new method and the parent implementation remains active.

python
class Dog(Animal):
    def speek(self) -> str:
        return "woof"

That bug is easy to miss. A static checker can flag it when @override is present, because there is no matching method to override in the base class.

This makes the decorator valuable in larger codebases where inheritance hierarchies evolve over time.

super() still matters

Indicating an override is separate from extending parent behavior. If you want the subclass method to build on the base implementation, call super().

python
1from typing import override
2
3
4class Logger:
5    def process(self, value: int) -> int:
6        print("base process")
7        return value
8
9
10class Doubler(Logger):
11    @override
12    def process(self, value: int) -> int:
13        original = super().process(value)
14        return original * 2
15
16
17print(Doubler().process(5))

The override marker says "this replaces a parent method." super() says "and I also want to reuse part of the parent implementation."

When static checking helps most

The @override decorator is most useful when you run a type checker such as mypy or pyright. In that workflow, incorrect overrides can be caught before runtime.

Practical examples:

  • refactoring a base class method name
  • large frameworks with many subclass hooks
  • plugin systems where subclasses implement framework methods

Without a checker, the decorator is still useful as documentation, but its main value is in tooling support.

You can still override without inheritance-heavy designs

Just because Python supports overriding does not mean inheritance is always the best design. In many cases:

  • composition is simpler
  • protocols or duck typing are enough
  • function injection is clearer than subclassing

So the right question is often not just "how do I mark an override," but also "should this design use inheritance at all."

Common Pitfalls

The most common mistake is assuming Python needs a built-in keyword similar to Java's @Override. It does not. Another is using inheritance and overrides when composition would be simpler and easier to test. Developers also sometimes think @override changes runtime behavior, but it mainly exists for clarity and static analysis. Misspelled method names are a practical risk when overriding without a checker. Finally, people often forget that overriding and calling super() are separate decisions: one signals replacement, the other controls reuse of parent behavior.

Summary

  • Python overrides methods by defining a method with the same name in a subclass.
  • No special keyword is required for overriding to work.
  • Use typing.override or typing_extensions.override to indicate intent explicitly.
  • The decorator is most useful with static type checkers.
  • Use super() only when you want to extend parent behavior, not merely override it.
  • Consider whether inheritance is the right design before focusing on override syntax.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Object-Oriented Design practice on Codemia

Turn requirements into classes, and defend the design, on the problems that come up in OOD rounds.

Practice OOD

All Rights Reserved.