Lesson 9 · 9 of 20
Inheritance and super() · Python
Reuse and specialise Python classes with inheritance: subclasses, super(), method overriding, isinstance and the MRO, using a payroll.

class Manager(Employee) creates a subclass: a Manager is an Employee and inherits everything it has (name, salary, describe()…) without rewriting it.
Manager's __init__ needs one more piece of data, bonus. Instead of copying the parent's code, it calls `super().__init__(name, salary)` so Employee sets up its part, and then adds its own. Intern has no __init__, so it uses the parent's as it is.
Both subclasses override monthly_pay(): a method with the same name replaces the inherited one. Manager reuses the parent's calculation with super().monthly_pay() and adds the bonus; Intern returns a fixed grant.
The powerful part is polymorphism: describe() is written once in Employee, yet self.monthly_pay() calls the method of the object's actual class each time, and type(self).__name__ prints that class. The loop treats everyone the same and each object answers in its own way.
isinstance(staff[1], Employee) is True because a manager is also an employee, and issubclass compares classes. Manager.__mro__ is the method resolution order: the list of classes Python searches for each method, from the most specific down to object.
Code · main.py
class Employee: def __init__(self, name, salary): self.name = name self.salary = salary def monthly_pay(self): return self.salary / 12 def describe(self): return f"{self.name:<6} {type(self).__name__:<9} {self.monthly_pay():>8.2f}"class Manager(Employee): # Manager is an Employee def __init__(self, name, salary, bonus): super().__init__(name, salary) # let the parent set its part self.bonus = bonus def monthly_pay(self): # override: same name, new behaviour return super().monthly_pay() + self.bonus / 12class Intern(Employee): def monthly_pay(self): return 800.0 # fixed grantstaff = [Employee("Lucia", 30000), Manager("Pablo", 48000, 6000), Intern("Iker", 0)]for person in staff: # the same call, the right method print(person.describe())print("Payroll:", round(sum(p.monthly_pay() for p in staff), 2))print("Pablo is an Employee:", isinstance(staff[1], Employee))print("Manager subclass of Employee:", issubclass(Manager, Employee))print("Method order:", [c.__name__ for c in Manager.__mro__])Output · python3 main.py
Lucia Employee 2500.00 Pablo Manager 4500.00 Iker Intern 800.00 Payroll: 7800.0 Pablo is an Employee: True Manager subclass of Employee: True Method order: ['Manager', 'Employee', 'object']
Key points
class Child(Parent)inherits attributes and methods.super()calls the parent's version.- A method with the same name overrides the inherited one.
isinstanceaccepts subclasses too.- The MRO is the order in which methods are looked up.
Exercise
Create a Contractor subclass paid by the hour (hours * rate) and add a contractor to staff so they show up in the payroll.