Skip to main content

Python Inheritance: Subclasses, Polymorphism, and super()

Intermediate25 min6 exercises85 XP
0/6 exercises

Think about how scientists classify animals. A Dog is a type of Mammal, which is a type of Animal. Each level inherits traits from the one above it: all animals breathe, all mammals are warm-blooded, and all dogs bark.

Python classes work the same way. A class can inherit from another class, automatically gaining all of its attributes and methods. The new class can then add its own features or change inherited ones.

In this tutorial, you'll learn how to create subclasses, override methods, use super() to call parent methods, and leverage polymorphism to write flexible code.

What Is Inheritance?

Inheritance lets you create a new class based on an existing one. The existing class is called the parent (or base class), and the new class is called the child (or subclass).

The child class automatically gets everything the parent has — all its methods and attributes. Then it can add new ones or change existing ones. You don't have to copy-paste any code.

Basic inheritance
Loading editor...

The Dog class has no code of its own (just pass), but it can already use name and speak() because it inherited them from Animal. That's the power of inheritance — free functionality from the parent.

How Do You Create Subclasses?

To make a child class, put the parent class name in parentheses after the child class name: class Child(Parent):. The child can then add its own attributes and methods.

Subclass with new attributes and methods
Loading editor...

The Dog class has its own __init__ that first calls the parent's __init__ using super(), then adds the breed attribute. It also adds a new method fetch() that Animal doesn't have.

How Do You Override Methods?

Sometimes the parent's method isn't quite right for the child. You can override it by defining a method with the same name in the child class. Python will use the child's version instead.

Overriding the speak() method
Loading editor...

Both Dog and Cat inherit from Animal, but each provides its own version of speak(). When Python calls buddy.speak(), it finds speak in the Dog class first, so it uses that version.

What Does super() Do?

Sometimes you want to extend a parent method rather than completely replace it. The super() function gives you access to the parent class, so you can call its methods from inside the child.

Using super() to extend a method
Loading editor...

super().describe() calls Animal.describe(), which returns 'I am Buddy'. Then Dog.describe() adds the breed info to create 'I am Buddy, a Golden Retriever'. This is much better than copy-pasting the parent's code.

Without super() (code duplication)
class Dog(Animal):
    def describe(self):
        # Duplicating Animal's logic
        return f'I am {self.name}, a {self.breed}'
With super() (reuse parent logic)
class Dog(Animal):
    def describe(self):
        base = super().describe()
        return f'{base}, a {self.breed}'

What Is Polymorphism?

Polymorphism means "many shapes." In programming, it means you can use different objects through the same interface. If multiple classes have a method with the same name, you can call that method on any of them without caring which class they belong to.

Polymorphism with a shared interface
Loading editor...

The for loop doesn't care if the object is a Dog, Cat, or Duck. It just calls speak() on each one, and each object responds in its own way. This makes your code flexible and easy to extend.

How Do isinstance() and issubclass() Work?

Sometimes you need to check what type an object is. Python gives you two built-in functions for this: isinstance() checks if an object is an instance of a class, and issubclass() checks if one class inherits from another.

Type checking with isinstance and issubclass
Loading editor...

Notice that isinstance(buddy, Animal) returns True even though buddy is a Dog. That's because a Dog is an Animal through inheritance. This is called the "is-a" relationship.

How Does Inheritance Work in a Real Project?

Let's build a small employee system where different types of employees calculate pay differently. This is a classic use case for inheritance and polymorphism.

Employee payroll system
Loading editor...

Both employee types share the same interface (calculate_pay()), but each computes pay differently. The loop doesn't need to know which type each employee is — it just calls calculate_pay() and gets the right result.


Practice Exercises

Create a Vehicle Subclass
Write Code

Given the Vehicle class below, create a Car subclass that:

  • Adds a doors attribute (set in __init__)
  • Calls the parent __init__ using super()
  • Create a Car with make 'Toyota', year 2023, and 4 doors. Print its make, year, and doors on separate lines.

    class Vehicle:
        def __init__(self, make, year):
            self.make = make
            self.year = year
    Loading editor...
    Override the describe() Method
    Write Code

    Given the Shape class, create a Circle subclass that:

  • Takes radius in __init__ and calls super().__init__('Circle')
  • Overrides describe() to return 'Circle with radius <radius>'
  • Create a Circle with radius 5 and print describe().

    class Shape:
        def __init__(self, shape_type):
            self.shape_type = shape_type
        def describe(self):
            return f'I am a {self.shape_type}'
    Loading editor...
    Predict the super() Output
    Predict Output

    Read the code carefully and predict what it prints. Pay attention to the order of super() calls and string concatenation.

    class A:
        def greet(self):
            return 'Hello'
    
    class B(A):
        def greet(self):
            return super().greet() + ' World'
    
    class C(B):
        def greet(self):
            return super().greet() + '!'
    
    obj = C()
    print(obj.greet())
    Loading editor...
    Fix the Inheritance Bug
    Fix the Bug

    This code has a bug causing an AttributeError. Fix it so it prints:

    Buddy (Golden Retriever) - Friendly
    Loading editor...
    Build a Shape Area Calculator
    Write Code

    Create a Shape base class with a method area() that returns 0. Then create two subclasses:

  • Square with a side attribute — area() returns side * side
  • Triangle with base and heightarea() returns 0.5 * base * height
  • Create a list with a Square(4) and a Triangle(6, 3). Loop through the list and print each area.

    Loading editor...
    Build a Notification System
    Write Code

    Build a notification system:

    1. Notification base class with __init__(self, message) and a send(self) method returning 'Sending: <message>'

    2. EmailNotification(Notification) with __init__(self, message, email). Override send() to return 'Email to <email>: <message>'

    3. SMSNotification(Notification) with __init__(self, message, phone). Override send() to return 'SMS to <phone>: <message>'

    Create one of each:

  • EmailNotification('Hello!', 'alice@test.com')
  • SMSNotification('Hi there!', '555-1234')
  • Loop through both and print send() for each.

    Loading editor...