Ereditarietà in Python
- #python
- #programmazione
- #oop
- #ereditarietà
- #classi
In questa lezione
- 1. Introduzione
- 2. Creare una classe base e una classe derivata
- 3. Il costruttore e la funzione super()
- 4. Aggiungere nuovi metodi o estendere quelli esistenti
- 5. Verificare relazioni di ereditarietà
- 7. La MRO (Method Resolution Order)
- 8. Classi astratte
- 9. Quiz a risposta multipla
- 10. Esercizi
- 10.1 Esercizio
- 10.2 Esercizio — Gestione di un Parco Veicoli Aziendale
1. Introduzione

L’ereditarietà (inheritance) è un principio fondamentale della programmazione orientata agli oggetti (OOP). Consente di riutilizzare e estendere il codice di una classe già esistente.
L’idea è semplice: una classe figlia (o sottoclasse) eredita attributi e metodi da una classe madre (o superclasse), potendo eventualmente modificarli o aggiungerne di nuovi.
Nota
L’ereditarietà promuove il riuso del codice e la manutenibilità, riducendo la duplicazione e rendendo il programma più modulare.
2. Creare una classe base e una classe derivata

class Animale:
def __init__(self, nome):
self.nome = nome
def parla(self):
print("L'animale emette un suono.")
Ora creiamo una classe derivata che eredita da Animale:
class Cane(Animale):
def parla(self):
print("Bau!")
Uso:
a = Animale("Creatura")
c = Cane("Fido")
a.parla() # L'animale emette un suono.
c.parla() # Bau!
Suggerimento
Se un metodo è definito sia nella classe base che nella classe derivata, Python usa quello della sottoclasse. Questo meccanismo si chiama override.
3. Il costruttore e la funzione super()
Quando una sottoclasse ha un proprio costruttore __init__, può comunque richiamare quello della classe base tramite super().
class Animale:
def __init__(self, nome):
self.nome = nome
class Cane(Animale):
def __init__(self, nome, razza):
super().__init__(nome) # chiama il costruttore della superclasse
self.razza = razza
Uso:
c = Cane("Fido", "Labrador")
print(c.nome, c.razza) # Output: Fido Labrador
Nota
super() permette di accedere ai metodi della superclasse, ed è il modo corretto per evitare errori di duplicazione o sovrascrittura involontaria.
4. Aggiungere nuovi metodi o estendere quelli esistenti
Le sottoclassi possono aggiungere nuovi metodi oppure estendere quelli ereditati.
class Animale:
def parla(self):
print("Suono generico.")
class Cane(Animale):
def parla(self):
super().parla() # chiama il metodo originale
print("Bau!")
c = Cane()
c.parla()
Output:
Suono generico.
Bau!
5. Verificare relazioni di ereditarietà
In Python una classe può ereditare da più superclassi. È una caratteristica potente, ma da usare con attenzione.
class Volante:
def vola(self):
print("Sto volando!")
class Nuotante:
def nuota(self):
print("Sto nuotando!")
class Anatra(Volante, Nuotante):
pass
a = Anatra()
a.vola()
a.nuota()
Output:
Sto volando!
Sto nuotando!
Attenzione
In caso di conflitti (metodi con lo stesso nome in più superclassi), Python risolve automaticamente l’ordine di ricerca con la MRO (Method Resolution Order).
7. La MRO (Method Resolution Order)
La MRO definisce l’ordine in cui Python cerca un attributo o metodo nelle classi coinvolte nell’ereditarietà multipla.
Possibile visualizzarla con:
print(Anatra.mro())
Output (esempio):
[<class '__main__.Anatra'>, <class '__main__.Volante'>, <class '__main__.Nuotante'>, <class 'object'>]
8. Classi astratte
A volte vogliamo definire una classe base che non sia istanziabile, ma che serva solo da modello per altre classi.
In Python si possono creare usando il modulo abc.
from abc import ABC, abstractmethod
class Animale(ABC):
@abstractmethod
def parla(self):
pass
class Cane(Animale):
def parla(self):
print("Bau!")
Uso:
c = Cane()
c.parla()
Nota
Una classe astratta:
- non può essere istanziata direttamente;
- può definire metodi “vuoti” che devono essere implementati nelle sottoclassi.
9. Quiz a risposta multipla
Mettiti alla prova
0/10 risposte
1) In Python, cosa rappresenta l'ereditarietà?
2) Qual è la parola chiave usata per creare una sottoclasse in Python?
3) Cosa fa la funzione super() in una sottoclasse?
4) Se una sottoclasse ridefinisce un metodo della superclasse, cosa succede?
5) Come si definisce una classe astratta in Python?
6) Quale tra questi metodi serve per verificare se un oggetto appartiene a una classe o sottoclasse?
7) In un'ereditarietà multipla, come decide Python l'ordine di ricerca dei metodi?
8) Quale delle seguenti affermazioni sul polimorfismo è corretta?
9) Cosa restituisce la chiamata print(ClasseFiglia.mro())?
10) Quando è opportuno usare una classe astratta?
10. Esercizi
10.1 Esercizio
Creare una gerarchia di classi che rappresenti veicoli:
- Classe base
Veicolocon attributo marca e metodoinfo(). - Classe
Autoche eredita daVeicoloe aggiungeporte. - Classe
Motoche eredita daVeicoloe aggiungecilindrata. - Sovrascrivere
info()in entrambe le sottoclassi per mostrare informazioni specifiche. - Creare alcune istanze e verifica l’uso di
isinstance()eissubclass().
10.2 Esercizio — Gestione di un Parco Veicoli Aziendale
Creare un programma orientato agli oggetti che gestisca diversi tipi di veicoli, sfruttando ereditarietà, polimorfismo e classi astratte.
Specifiche:
-
Creare una classe base astratta
Veicolocon:- attributi:
marca,modello,anno,targa - metodo
descrizione()che restituisce una stringa con le informazioni del veicolo - metodo
eta()che calcola l’età come differenza tra la data attuale e l’anno di immatricolazione - metodo astratto
calcola_costo_manutenzione()
- attributi:
-
Creare le sottoclassi:
Auto→ aggiungenumero_porteetipo_carburanteMoto→ aggiungecilindrataCamion→ aggiungeportata_massima
-
In ciascuna sottoclasse:
- Sovrascrivere
calcola_costo_manutenzione()con formule diverse- Auto:
100 + 10 * età - Moto:
80 + 5 * età - Camion:
200 + 20 * età
- Auto:
- Ridefinire
descrizione()per includere gli attributi specifici
- Sovrascrivere
-
Creare una classe
ParcoVeicoliche:- Contenga una lista di veicoli
- Permetta di aggiungere nuovi veicoli (
aggiungi_veicolo()) - Stampi tutti i veicoli con
stampa_veicoli() - Calcoli il costo totale di manutenzione annuale
- Ordini i veicoli in base al costo di manutenzione
-
Aggiungere un metodo di classe
numero_veicoli()nella classe base per contare quanti veicoli sono stati creati.
Suggerimento:
Usare il modulo datetime per calcolare l’età dei veicoli