Skip to main content
eLearner.app
Module 7 · Lesson 2 of 426/36 in the course~12 min
Module lessons (2/4)

Inheritance

Inheritance lets you create a new class (the subclass) that inherits attributes and methods from an existing class (the base class), and can extend or override them.

Basic syntax

Python
class Animale:
    def __init__(self, nome):
        self.nome = nome

    def saluta(self):
        return f"{self.nome} fa un verso"

class Cane(Animale):       # Cane EREDITA da Animale
    def saluta(self):       # OVERRIDE del metodo
        return f"{self.nome} dice WOOF!"

a = Animale("X")
c = Cane("Fido")
a.saluta()      # 'X fa un verso'
c.saluta()      # 'Fido dice WOOF!'

Cane inherits __init__ from Animale without rewriting it.

super(): calling the base method

When you want to extend a base method (not completely replace it), use super():

Python
class Animale:
    def __init__(self, nome):
        self.nome = nome

class Cane(Animale):
    def __init__(self, nome, razza):
        super().__init__(nome)    # delega alla base
        self.razza = razza

c = Cane("Fido", "Labrador")
c.nome        # 'Fido'
c.razza       # 'Labrador'

isinstance: type check

Python
isinstance(c, Cane)        # True
isinstance(c, Animale)     # True (anche la base)
isinstance(c, str)         # False

isinstance(x, BaseClass) also recognizes all subclasses: this is what makes inheritance useful for polymorphism.

Python
animali = [Cane("Fido", "X"), Animale("Pippo")]
for a in animali:
    print(a.saluta())        # ogni oggetto risponde a suo modo

MRO (Method Resolution Order) — overview

When you have multiple inheritance, Python decides in which order to look for a method by following the MRO, computed with the C3 algorithm. For 95% of cases it is enough to know:

  1. it looks first in the instance,
  2. then in its class,
  3. then in the base classes in declaration order.
Python
Cane.__mro__
# (<class 'Cane'>, <class 'Animale'>, <class 'object'>)

object is the root of every class in Python 3.

Your turn

Exercise#python.m7.l2.e1
Attempts: 0Loading…

Given `class Vehicle: def __init__(self, brand): self.brand = brand`, define `Car(Vehicle)` with __init__(self, brand, model) that calls super().__init__ and stores self.model. Create `a = Car('Fiat', '500')` and evaluate `(a.brand, a.model)`.

Loading editor…
Show hint

super().__init__(brand) then self.model = model.

Solution available after 3 attempts

Review exercise

Exercise#python.m7.l2.e2
Attempts: 0Loading…

Define `class Shape: def area(self): return 0` and `class Square(Shape)` with __init__(self, side) and area() that returns side * side. Create `q = Square(5)` and evaluate the tuple `(q.area(), isinstance(q, Shape))`.

Loading editor…
Show hint

self.side * self.side.

Solution available after 3 attempts

Additional challenge

Exercise#python.m7.l2.e3
Attempts: 0Loading…

Create a class `Square` that inherits from the `Rectangle` class (defined below). The constructor of `Square` must take a single parameter `side` and pass it to `super().__init__(side, side)`. Instantiate a square with side `6` in `sq` and evaluate `sq.area()`.

Loading editor…
Show hint

Declare class Square(Rectangle): and call super().__init__(side, side) in the constructor.

Solution available after 3 attempts