Legends ofPythos
Claim your name
Objects and Classes

super() and overriding

Lesson 9 of 13

Watch the lesson1:14 · with Torsten
Inheritance lets a child class reuse its parent’s code. But real programs often need the child to behave differently in specific spots while keeping everything else intact. That is where overriding and super() come together.

The mental model

Overriding a method

class Vehicle:
    def start(self):
        return "Engine roars"

class ElectricCar(Vehicle):
    def start(self):
        return "Silent hum"
ElectricCar replaces the parent’s start entirely.
When you call my_car.start(), Python looks at the object’s actual class first. Because ElectricCar defines its own start, that version wins and Vehicle.start is never touched for this instance.

Using super() to extend, not replace

class Employee:
    def __init__(self, name):
        self.name = name

class Manager(Employee):
    def __init__(self, name, team_size):
        super().__init__(name)
        self.team_size = team_size
super().__init__() runs the parent’s setup before adding team_size.
Without that line, a Manager object would have no .name, and any method expecting it would crash. The call hands control to the parent constructor with exactly the arguments it needs, then returns so you can finish your own setup.

Calling the parent’s behaviour inside an override

class Shape:
    def describe(self):
        return "generic shape"

class Square(Shape):
    def describe(self):
        base = super().describe()
        return f"{base} with four equal sides"
super().describe() fetches the parent’s string, then you build on it.
The example shows a pattern: grab what the parent already gives you, append or transform it, and return the richer result. You keep DRY code instead of copying the parent logic into every child class.

A common mistake

You will see this pattern everywhere: base classes for API clients that set up auth headers in __init__, then subclasses add rate-limiting; logging handlers where a child formats messages differently but still calls the parent’s write. Master overriding and super() now, and those extensions feel natural instead of fragile.

Your turn

0 of 3 solved

Exercise 1

+40 XP
Create two classes, Shape and Square. Give Shape.__init__ a single argument name stored as self.name, and give it an area method that returns 0. Create Square(Shape) with its own __init__(side) which calls super().__init__('square') first then sets self.side to side. Then override the area method in Square so it returns side squared (i.e., side * side).
Write your Python here.

Run your code to check it against the tests.

Exercise 2

+40 XP
Build Vehicle and ElectricCar. Vehicle.__init__(make) stores make as self.make. Give Vehicle a start method that returns the string 'Engine roaring'. ElectricCar should inherit from Vehicle. Its __init__ should accept (make, battery_kw), call super().__init__(make), then set self.battery_kw to battery_kw. Override its start method so it calls super().start() and appends ', silent' at the end.
Write your Python here.

Run your code to check it against the tests.

Exercise 3

+40 XP
Create Employee and Manager. Employee.__init__(name, salary) stores both as self.name and self.salary. Give it a pay method that returns the string 'pays <salary>' (use an f-string). Manager should inherit from Employee. Its __init__ should accept (name, salary, team_size), call super().__init__(name, salary), then set self.team_size to team_size. Override its pay method so it calls super().pay() and appends ' plus bonus' at the end.
Write your Python here.

Run your code to check it against the tests.