Ereditarietà, Incapsulamento, Polimorfismo
📚 Contenuti teorici
🔹 1. Ereditarietà
È il meccanismo per cui una classe figlia (o derivata) può ereditare attributi e metodi da una classe madre (o base).
Esempio semplice in Python:
class Veicolo:
def __init__(self, marca):
self.marca = marca
def accendi_motore(self):
print("Motore acceso")
class Auto(Veicolo): # Auto eredita da Veicolo
def apri_portiere(self):
print("Portiere aperte")
mia_auto = Auto("Fiat")
mia_auto.accendi_motore() # Metodo ereditato
mia_auto.apri_portiere() # Metodo della classe Auto
🧩 Osservazione: Auto eredita tutto da Veicolo ma può aggiungere comportamenti nuovi o sovrascrivere quelli esistenti.
🔹 2. Incapsulamento
Significa nascondere i dettagli interni e proteggere i dati usando modificatori di accesso e metodi per leggere/scrivere valori.
Esempio in Python con getter
e setter
:
class ContoBancario:
def __init__(self):
self.__saldo = 0 # Attributo privato
def deposita(self, importo):
if importo > 0:
self.__saldo += importo
def get_saldo(self):
return self.__saldo
conto = ContoBancario()
conto.deposita(100)
print(conto.get_saldo()) # Accesso controllato
🔐 Nota: L’attributo __saldo
è privato, accessibile solo tramite i metodi pubblici. Questo è l’incapsulamento.
🔹 3. Polimorfismo
Con il polimorfismo, più classi possono usare lo stesso nome di metodo, ma con comportamenti diversi.
Esempio con metodo muoviti()
sovrascritto:
class Veicolo:
def muoviti(self):
print("Il veicolo si muove")
class Bicicletta(Veicolo):
def muoviti(self):
print("La bicicletta pedala")
class Auto(Veicolo):
def muoviti(self):
print("L'auto accelera")
# Polimorfismo:
veicoli = [Bicicletta(), Auto()]
for v in veicoli:
v.muoviti() # Comportamento specifico della sottoclasse
👥 Osservazione: Lo stesso metodo muoviti()
si comporta diversamente in base al tipo di oggetto.
⚙️ 4. Perché sono importanti questi concetti
- Modularità: il codice è organizzato meglio.
- Riutilizzabilità: si scrive meno codice duplicato.
- Flessibilità: si possono cambiare singole parti senza riscrivere tutto.
- Manutenibilità: più facile da leggere e modificare.
🧪 Attività pratiche
✅ 1. Crea una gerarchia di classi
Obiettivo: progettare classi che sfruttano ereditarietà.
Esempio:
class Animale:
def parla(self):
print("L’animale fa un suono")
class Cane(Animale):
def parla(self):
print("Il cane abbaia")
class Gatto(Animale):
def parla(self):
print("Il gatto miagola")
animali = [Cane(), Gatto()]
for a in animali:
a.parla()
🧠 Sfida: aggiungi una terza sottoclasse (Es. Mucca) che implementa parla()
.
✅ 2. Incapsula gli attributi
Crea una classe Studente
con nome e voto. Proteggi il voto e usa metodi per modificarlo solo se il valore è compreso tra 0 e 10.
class Studente:
def __init__(self, nome):
self.nome = nome
self.__voto = 0
def set_voto(self, valore):
if 0 <= valore <= 10:
self.__voto = valore
def get_voto(self):
return self.__voto
✅ 3. Polimorfismo in azione
Scrivi una funzione saluta(animal)
che chiama parla()
su qualsiasi tipo di animale.
def saluta(animal):
animal.parla()
saluta(Cane()) # "Il cane abbaia"
saluta(Gatto()) # "Il gatto miagola"
❓ Test di verifica
✍️ Domande a risposta multipla
1. Qual è lo scopo dell’incapsulamento?
A. Accelerare il codice
B. Proteggere i dati → ✅
C. Rendere il codice più lungo
D. Fare debug
2. Quale simbolo in Python indica un attributo privato?
A. #
B. *
C. __
→ ✅
D. @
3. Il polimorfismo permette di...
A. Scrivere funzioni molto complesse
B. Usare lo stesso metodo in più modi → ✅
C. Copiare classi
D. Moltiplicare variabili
🤖 Quiz interattivo a completamento
Completa il metodo parla
nella classe Gatto per far stampare “Miagolio!”
class Gatto(Animale):
def parla(self):
____________
Soluzione: print("Miagolio!")
🔄 Attività di riepilogo
🎲 Gioco: Chi eredita cosa?
- Mostra una lista di metodi e classi.
- Chiedi: “Quali classi hanno accesso al metodo X?”
🧩 Puzzle OOP:
- Dai istruzioni mischiate (metodi, classi, relazioni).
- Gli studenti devono ricostruire la gerarchia.
Nessun commento:
Posta un commento