Skip to content
FollowtheDamnCode

Inheritance

Child classes, overriding, and super().

5 minute read

Big idea

Inheritance builds a new class on top of an existing one. The child class gets everything the parent has, and can add to it or override parts of it.

The idea

Animals that speak differently
class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        return "..."

    def introduce(self):
        print(f"I'm {self.name}. {self.speak()}")

class Dog(Animal):
    def speak(self):
        return "Woof!"

class Cat(Animal):
    def speak(self):
        return "Meow."

for pet in [Dog("Rex"), Cat("Tom"), Animal("Blob")]:
    pet.introduce()
output
I'm Rex. Woof!
I'm Tom. Meow.
I'm Blob. ...

Run and edit it in the app.

  • class Dog(Animal): — Dog inherits from Animal.
  • Dog never defines __init__ or introduce, but has both — inherited.
  • Dog's own speak overrides Animal's.
  • The loop calls introduce on each pet, and each one uses its own speak. One call, different behaviour — that's called polymorphism.
Dog and Cat are kinds of Animal

super(): extending the parent

When a child needs extra attributes, its __init__ calls the parent's with super() and then adds its own:

Predict: a student is a person
class Person:
    def __init__(self, name):
        self.name = name

    def describe(self):
        return self.name

class Student(Person):
    def __init__(self, name, school):
        super().__init__(name)
        self.school = school

    def describe(self):
        return super().describe() + " studies at " + self.school

s = Student("Ada", "Hilltop")
print(s.describe())
print(isinstance(s, Person))
What does it print? Show the answer
Ada studies at Hilltop
True

Run and edit it in the app.

isinstance(s, Person) is True: a Student is a Person.

Fix the bug: the circle's area should be 12.57
import math

class Shape:
    def area(self):
        return 0

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

    def are(self):
        return math.pi * self.r ** 2

print(round(Circle(2).area(), 2))
output
12.57

Run and edit it in the app.

A typo in the method name means Circle never overrides area — it silently inherits Shape's version, which returns 0.

When to inherit

Use inheritance for a true "is a" relationship: a Dog is an Animal. If it's "has a" — a Car has an Engine — store the other object as an attribute instead. Keep hierarchies shallow; one or two levels is plenty.

A child class defines a method with the same name as its parent's. Which runs when you call it on a child object?

Watch it

Think of it like

A family recipe. You inherit grandma's lasagne recipe whole, then change one step — more garlic. Everything you didn't change still works exactly the way she wrote it.

Key terms

  • Inheritance — A class built from another, getting its attributes and methods.
  • Override — Redefining an inherited method in the child.
  • super() — Reaches the parent class's version of a method.
  • Polymorphism — The same call doing different things for different classes.

Check yourself

In class Dog(Animal): which is the parent?

What does super().__init__(name) do?

Which relationship suits inheritance?