Method Overriding

RoadmapsPython

Overview

Method overriding allows a subclass to provide a specific implementation of a method that is already defined in its superclass. When you call the method on a subclass instance, Python uses the subclass's version instead of the parent's. Think of it like a franchise restaurant: the parent company defines a default menu, but a local branch can override specific items to cater to regional tastes. In Python, this is how we specialize behavior while sharing a common interface. You typically override methods to achieve one of two things: - Replace behavior: Provide a completely new implementation without calling the parent. - Extend behavior: Add new logic and call the parent's original method using `super()`. class Parent: def process(self, data): return True class Child(Parent): # TRAP: Adding a mandatory argument changes the signature def process(self, data, config): return True Child().process("data") # TypeError: missing 1 required argument: 'config' When overriding a method, changing the mandatory arguments breaks any code that relies on the parent's interface. This violates the Liskov Substitution Principle, which is covered fully in protocols.

It enables polymorphism, allowing different objects to respond to the same method call in their own specific way without needing complex `if` statements.

Where used: Django class-based views, Pydantic validators, FastAPI dependencies

Why learn this

Code walkthrough

class User:
    def get_role(self):
        return 'Guest'

class Admin(User):
    def get_role(self):
        return 'Administrator'

user = User()
print(user.get_role())
admin = Admin()
print(admin.get_role())

Focus: `def get_role(self):` in `Admin` class intercepts the call

Aha moment

class BaseConfig:
    def load(self):
        print('Loading defaults')
        self.setup()

    def setup(self):
        print('Base setup')

class AppConfig(BaseConfig):
    def setup(self):
        print('App setup')

config = AppConfig()
config.load()

Prediction: What is printed when config.load() is called?

Common guess: `Loading defaults` followed by `Base setup`, because `load()` is defined in `BaseConfig`.

Even though `load()` is defined in the parent class, `self` refers to the `AppConfig` instance. So `self.setup()` dynamically resolves to the overridden `setup()` method in the subclass.

Common mistakes

Glossary

specialize
To modify or narrow down a general behavior into a more specific implementation for a particular situation, e.g. overriding `Animal.speak()` in `Dog` to return `'Woof'` instead of a generic sound.
subclass
A new class that inherits properties and methods from an existing, parent class, e.g. `class Admin(User)` is a subclass of `User`.

Recall questions

Understanding checks

What is printed when `c.greet()` is called?

`Hello Child` `Hello Parent`

The `Child` class overrides the `greet` method. When called, it first prints `'Hello Child'`, and then explicitly calls the `Parent`'s `greet` method using `super()`, which prints `'Hello Parent'`.

Why might code that uses a subclass crash if the subclass overrides a method with a different number of arguments?

If a method is overridden with a different signature, any code expecting the parent class's original method signature will pass the wrong number of arguments, leading to a `TypeError`.

This violates the Liskov Substitution Principle. A subclass should be able to replace its parent without breaking existing code.

Practice tasks

Override the Payment Process

Modify the starter code by creating a `CreditCardPayment` subclass that inherits from `Payment`. Override its `process()` method to print `'Processing credit card payment'`, completely replacing the parent's behavior.

Challenge

Extend, Don't Replace

Create an `APIHandler` with a `handle_request()` method that prints `'Authenticating request'`. Create a `SecureAPIHandler` subclass that overrides `handle_request()`. It should first call the parent's `handle_request()`, and then print `'Encrypting payload'`.

Continue learning

Previous: Class Creation and Instantiation

Previous: Single inheritance and super()

Previous: Instance, Class, and Static Methods

Next: Duck Typing

Next: Structural Subtyping with Protocols

Return to Python Roadmap