BrightPath
Back to Course
Year 12 Coding

Python Inheritance

Understand how to create parent and child classes, use super(), override methods, and apply polymorphism in Python.

What is Inheritance?

Inheritance allows a new class (the child or subclass) to inherit attributes and methods from an existing class (the parent or superclass). This promotes code reuse and creates a logical hierarchy.

The child class can use everything from the parent, add its own unique features, or override parent methods to provide specialised behaviour.

class Animal:
    def __init__(self, name, species):
        self.name = name
        self.species = species

    def speak(self):
        return f"{self.name} makes a sound"

class Dog(Animal):  # Dog inherits from Animal
    def __init__(self, name, breed):
        super().__init__(name, "Canine")  # call parent __init__
        self.breed = breed

    def speak(self):  # override parent method
        return f"{self.name} barks!"

buddy = Dog("Buddy", "Labrador")
print(buddy.species)   # Canine (inherited attribute)
print(buddy.speak())   # Buddy barks! (overridden method)

The super() function calls the parent class's method, letting you extend rather than replace behaviour.

Method Overriding and super()

When a child class defines a method with the same name as one in the parent, it overrides the parent's version. You can still access the parent's implementation using super().

class Vehicle:
    def __init__(self, make, year):
        self.make = make
        self.year = year

    def describe(self):
        return f"{self.year} {self.make}"

class ElectricCar(Vehicle):
    def __init__(self, make, year, battery_kwh):
        super().__init__(make, year)  # reuse parent init
        self.battery_kwh = battery_kwh

    def describe(self):  # override with extra info
        base = super().describe()  # get parent's description
        return f"{base} (Electric, {self.battery_kwh} kWh)"

tesla = ElectricCar("Tesla Model 3", 2025, 75)
print(tesla.describe())
# 2025 Tesla Model 3 (Electric, 75 kWh)

Polymorphism

Polymorphism means "many forms." It allows different classes to be treated through the same interface. When multiple classes implement the same method name, you can call that method on any of them without knowing the specific class.

class Shape:
    def area(self):
        raise NotImplementedError("Subclasses must implement area()")

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

    def area(self):
        import math
        return math.pi * self.radius ** 2

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

# Polymorphism in action
shapes = [Circle(5), Rectangle(4, 6), Circle(3)]
for shape in shapes:
    print(f"{type(shape).__name__}: area = {shape.area():.2f}")
# Circle: area = 78.54
# Rectangle: area = 24.00
# Circle: area = 28.27

Each shape calculates its area differently, but we call .area() on all of them uniformly. This is polymorphism.

Key Vocabulary

Inheritance

A mechanism where a child class receives attributes and methods from a parent class.

super()

A built-in function that returns a proxy object allowing you to call methods from the parent class.

Method Overriding

When a child class redefines a method inherited from its parent class with its own implementation.

Polymorphism

The ability of different classes to respond to the same method call in their own way.

Worked Examples

1

Create an Employee hierarchy with a Manager subclass

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

    def get_pay(self):
        return self.salary

    def __str__(self):
        return f"{self.name} (${self.salary:,.0f}/yr)"

class Manager(Employee):
    def __init__(self, name, salary, bonus):
        super().__init__(name, salary)
        self.bonus = bonus

    def get_pay(self):
        return self.salary + self.bonus

    def __str__(self):
        return f"{self.name} (${self.get_pay():,.0f}/yr incl. bonus)"

emp = Employee("Alice", 70000)
mgr = Manager("Bob", 90000, 15000)
print(emp)           # Alice ($70,000/yr)
print(mgr)           # Bob ($105,000/yr incl. bonus)
print(mgr.get_pay()) # 105000

Key point: Manager overrides both get_pay() and __str__() while reusing the parent's __init__ via super().

2

Use isinstance() and issubclass() to check relationships

class Animal:
    pass

class Dog(Animal):
    pass

class Cat(Animal):
    pass

rex = Dog()
whiskers = Cat()

print(isinstance(rex, Dog))       # True
print(isinstance(rex, Animal))    # True (Dog IS an Animal)
print(isinstance(rex, Cat))       # False

print(issubclass(Dog, Animal))    # True
print(issubclass(Cat, Dog))       # False

isinstance() checks if an object is an instance of a class (or its parents). issubclass() checks the class hierarchy directly.

3

Multiple inheritance and method resolution order (MRO)

class Flyer:
    def move(self):
        return "Flying through the air"

class Swimmer:
    def move(self):
        return "Swimming through water"

class Duck(Flyer, Swimmer):
    pass  # inherits from both

donald = Duck()
print(donald.move())  # Flying through the air (Flyer comes first)

# Check the Method Resolution Order
print(Duck.__mro__)
# (Duck, Flyer, Swimmer, object)

MRO determines which parent method is called when there is a conflict. Python uses the C3 linearisation algorithm, checking left-to-right in the inheritance list.

Knowledge Check

Select the correct answer for each question. Click "Check Answer" to see if you are right.

Question 1

What does super().__init__() do inside a child class?

Question 2

What is method overriding?

Question 3

Given class Cat(Animal), what does isinstance(my_cat, Animal) return?

Question 4

What is polymorphism in OOP?

Question 5

In class Duck(Flyer, Swimmer), which class's move() method is called first?

Key Concepts Summary

Previous: Python OOP Next: Data Structures