Auto elettriche e sportive senza riscrivere codice: classi figlie, virtual e override, e una sola List per tutti i tipi di auto.
Ultima tappa del Parco Auto. Riparti dal progetto delle lezioni Parco Auto 1 e Parco Auto 2: la classe Automobile c'รจ giร , e ora le diamo dei figli.
Ereditarietร : Le Classi Figlie
Hai creato la classe Automobile. Ma cosa succede se vuoi gestire anche
AutoElettrica o AutoSportiva?
Hanno molte cose in comune con Automobile, ma anche caratteristiche diverse.
Devi riscrivere tutto da capo? No! Esiste l'ereditarietร .
๐ค Il Problema Senza Ereditarietร
โ SENZA Ereditarietร - Codice Duplicato
// Devi scrivere due classi SEPARATE con tutto il codice ripetuto
class Automobile
{
private string _modello;
private int _cilindrata;
private string _carburante;
// ... costruttore, proprietร , metodi ...
}
class AutoElettrica
{
private string _modello; // โ DUPLICATO!
private int _cilindrata; // โ DUPLICATO!
private string _carburante; // โ DUPLICATO!
private int _autonomiaKm; // Nuovo campo specifico
// ... tutto il costruttore duplicato ...
// ... tutte le proprietร duplicate ...
}
// ๐ฑ Problemi:
// 1. Codice identico scritto due volte โ errori facilissimi
// 2. Se devi correggere un bug, devi farlo in ENTRAMBE le classi
// 3. Non รจ scalabile: per 10 tipi di auto, 10 classi duplicate!
โ CON Ereditarietร - Codice Riutilizzato
โ CON Ereditarietร - DRY (Don't Repeat Yourself)
// La classe BASE ha tutto il codice comune
class Automobile
{
private string _modello;
private int _cilindrata;
private string _carburante;
// ... proprietร e metodi comuni a TUTTE le auto ...
}
// La classe FIGLIA eredita tutto e aggiunge solo il nuovo
class AutoElettrica : Automobile // โ Il ":" significa "estende"
{
private int _autonomiaKm; // Solo la parte NUOVA!
// tutto il resto lo prende GRATIS da Automobile!
}
// โ
Vantaggi:
// 1. AutoElettrica ha giร Modello, Cilindrata, Carburante
// 2. Correggi un bug in Automobile โ fix automatico per tutti
// 3. Aggiungi 10 tipi di auto senza duplicare nulla
๐ฏ Analogia del Mondo Reale
Pensa alla biologia:
- Animale (classe base) โ respira, si muove, ha un nome
- Cane (classe figlia) โ eredita tutto da Animale + abbaia, ha una razza
- Gatto (classe figlia) โ eredita tutto da Animale + fa le fusa, รจ indipendente
Il Cane non deve "reimparare" a respirare: lo eredita dall'Animale!
Automobile (CLASSE BASE / GENITORE)
โโโ Modello
โโโ Cilindrata
โโโ Carburante
โโโ ToString()
โ
โโโโโโโโโโโโโผโโโโโโโโโโโโ
โ โ โ
AutoElettrica AutoSportiva AutoLusso
(FIGLIA) (FIGLIA) (FIGLIA)
+ AutonomiaKm + Cavalli + Prezzo
+ Batteria + Turbo + Brand
Come Si Scrive una Classe Figlia
- Modificare la Classe Base: aggiungere
protected
Prima di creare classi figlie, devi modificare la classe Automobile.
Le classi figlie non possono accedere ai campi private del genitore.
Devi usare protected:
Automobile.cs - Campi diventano protected
public class Automobile
{
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// PRIMA usavi "private" โ SOLO questa classe poteva vederli
// ORA usi "protected" โ anche le classi FIGLIE possono vederli
// Dall'esterno (Form, altri) rimangono comunque nascosti!
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
protected string _modello; // โ protected, non private
protected int _cilindrata; // โ protected, non private
protected string _carburante; // โ protected, non private
// Le PROPRIETร e i METODI pubblici rimangono uguali
public string Modello
{
get { return _modello; }
set { if (!string.IsNullOrEmpty(value)) _modello = value; }
}
public int Cilindrata
{
get { return _cilindrata; }
set { if (value >= 500 && value <= 10000) _cilindrata = value; }
}
public string Carburante
{
get { return _carburante; }
set { if (!string.IsNullOrEmpty(value)) _carburante = value; }
}
// Il costruttore rimane uguale
public Automobile(string modello, int cilindrata, string carburante)
{
Modello = modello;
Cilindrata = cilindrata;
Carburante = carburante;
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// IMPORTANTE: aggiungi "virtual" ai metodi che le figlie
// potranno personalizzare (override)
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
public virtual string Stampa()
{
return $"{Modello} - {Cilindrata}cc - {Carburante}";
}
public override string ToString()
{
return Stampa();
}
}
๐ I Tre Livelli di Visibilitร
| Parola chiave | Chi puรฒ accedere? | Quando usarla |
|---|---|---|
private |
Solo la classe stessa | Se non hai classi figlie |
protected |
La classe + le classi figlie | Quando usi l'ereditarietร โ |
public |
Tutti (Form, altre classi...) | Proprietร e metodi pubblici |
- Creare la Classe Figlia:
AutoElettrica
Aggiungi un nuovo file AutoElettrica.cs al progetto (come hai fatto per Automobile.cs).
AutoElettrica.cs - Classe Figlia Completa
using System;
using System.Windows.Forms;
namespace ParcoAuto
{
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// AutoElettrica ESTENDE Automobile
// Il ":" indica "eredita da"
// Leggi: "AutoElettrica รจ un tipo di Automobile"
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
public class AutoElettrica : Automobile
{
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// CAMPI PRIVATI propri di AutoElettrica
// (quelli di Automobile li ha giร ereditati!)
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
private int _autonomiaKm;
private int _percentualeBatteria;
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// PROPRIETร proprie di AutoElettrica
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
public int AutonomiaKm
{
get { return _autonomiaKm; }
set
{
if (value >= 50 && value <= 1000) { _autonomiaKm = value; } else { MessageBox.Show("Autonomia deve essere tra 50 e 1000 km!", "ERRORE", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } public int PercentualeBatteria { get { return _percentualeBatteria; } set { if (value >= 0 && value <= 100)
_percentualeBatteria = value;
else
MessageBox.Show("Percentuale batteria deve essere tra 0 e 100!",
"ERRORE", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// PROPRIETร CALCOLATA: km rimasti con la carica attuale
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
public double KmRimasti
{
get { return _autonomiaKm * (_percentualeBatteria / 100.0); }
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// COSTRUTTORE della classe figlia
// Deve chiamare il costruttore del GENITORE con "base(...)"
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
public AutoElettrica(string modello, int autonomiaKm, int percentualeBatteria)
: base(modello, 0, "Elettrica") // โ chiama Automobile(modello, 0, "Elettrica")
{
// Dopo che il costruttore base ha fatto il suo lavoro,
// impostiamo le proprietร specifiche di AutoElettrica
AutonomiaKm = autonomiaKm;
PercentualeBatteria = percentualeBatteria;
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// OVERRIDE di Stampa() โ versione personalizzata
// Sostituisce la versione del genitore
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
public override string Stampa()
{
return $"{Modello} [โก Elettrica] - Autonomia: {AutonomiaKm}km - " +
$"Batteria: {PercentualeBatteria}% ({KmRimasti:F0}km rimasti)";
}
// ToString() NON serve riscriverlo! Chiama giร Stampa()
// che ora รจ la versione override di AutoElettrica โ
}
}
๐ Analisi del Costruttore Figlia
public AutoElettrica(string modello, int autonomiaKm, int percentualeBatteria)
: base(modello, 0, "Elettrica")
// โ
// "base(...)" = chiama il costruttore di AUTOMOBILE
// Gli passo: modello (dall'utente), 0 (cilindrata 0 per elettrica),
// "Elettrica" (carburante fisso)
//
// ORDINE di esecuzione:
// 1. Prima viene eseguito il costruttore di Automobile (base)
// โ imposta _modello, _cilindrata, _carburante
// 2. Poi viene eseguito il corpo di AutoElettrica
// โ imposta _autonomiaKm, _percentualeBatteria
- Creare una Seconda Figlia:
AutoSportiva
AutoSportiva.cs
namespace ParcoAuto
{
public class AutoSportiva : Automobile
{
private int _cavalliVapore;
private bool _hasTurbo;
public int CavalliVapore
{
get { return _cavalliVapore; }
set
{
if (value >= 100 && value <= 2000)
_cavalliVapore = value;
else
MessageBox.Show("Cavalli vapore devono essere tra 100 e 2000!",
"ERRORE", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public bool HasTurbo
{
get { return _hasTurbo; }
set { _hasTurbo = value; }
}
// Costruttore: chiama base per modello, cilindrata, carburante
public AutoSportiva(string modello, int cilindrata, string carburante,
int cavalliVapore, bool hasTurbo)
: base(modello, cilindrata, carburante)
{
CavalliVapore = cavalliVapore;
HasTurbo = hasTurbo;
}
// Override personalizzato per AutoSportiva
public override string Stampa()
{
string turbo = HasTurbo ? " [TURBO]" : "";
return $"{Modello} [๐๏ธ Sport]{turbo} - {Cilindrata}cc - " +
$"{CavalliVapore}cv - {Carburante}";
}
}
}
Override: Personalizzare i Metodi Ereditati
override significa letteralmente "sostituire".
Una classe figlia puรฒ riscrivere un metodo del genitore per dargli un comportamento diverso,
piรน adatto al suo tipo specifico.
๐ Le Tre Parole Chiave: virtual, override, base
| Parola chiave | Dove si mette | Cosa significa |
|---|---|---|
virtual |
Nel metodo della classe BASE | "Questo metodo puรฒ essere riscritto dalle figlie" |
override |
Nel metodo della classe FIGLIA | "Sostituisco la versione del genitore con la mia" |
base.Metodo() |
Dentro l'override della FIGLIA | "Richiama anche il metodo originale del genitore" |
Esempio completo - virtual, override, base
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// CLASSE BASE
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
public class Automobile
{
public virtual string Stampa() // โ virtual: "puรฒ essere overridato"
{
return $"{Modello} - {Cilindrata}cc - {Carburante}";
}
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// CLASSE FIGLIA - Override completo
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
public class AutoElettrica : Automobile
{
public override string Stampa() // โ override: "sostituisco la versione base"
{
// Versione completamente nuova, ignora quella di Automobile
return $"{Modello} [โก] - Autonomia: {AutonomiaKm}km";
}
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// CLASSE FIGLIA - Override con base (estende senza perdere)
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
public class AutoSportiva : Automobile
{
public override string Stampa()
{
// Richiama il metodo del genitore e CI AGGIUNGE qualcosa
string testoBase = base.Stampa(); // โ "base." chiama Automobile.Stampa()
// testoBase = "Ferrari 488 - 3900cc - Benzina"
return testoBase + $" | {CavalliVapore}cv";
// Risultato: "Ferrari 488 - 3900cc - Benzina | 660cv"
}
}
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// Risultato nelle listbox:
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// Automobile normale: "Fiat 500 - 1200cc - Benzina"
// AutoElettrica: "Tesla [โก] - Autonomia: 500km"
// AutoSportiva: "Ferrari 488 - 3900cc - Benzina | 660cv"
โ ๏ธ Errore Comune: dimenticare "virtual"
// โ SBAGLIATO: metodo nella base senza "virtual"
public class Automobile
{
public string Stampa() // โ manca "virtual"!
{
return $"{Modello} - {Cilindrata}cc";
}
}
public class AutoElettrica : Automobile
{
public override string Stampa() // ๐ฅ ERRORE di compilazione!
// "non si puรฒ fare override di un metodo non-virtual"
{ ... }
}
// โ
SOLUZIONE: aggiungi "virtual" nella classe base
public class Automobile
{
public virtual string Stampa() // โ ora le figlie possono overridarlo
{ ... }
}
Polimorfismo: Un'Unica Lista per Tutti i Tipi
Polimorfismo viene dal greco: "molte forme". ร il concetto piรน potente dell'ereditarietร : puoi trattare oggetti di tipo diverso come se fossero tutti dello stesso tipo base.
๐ค Il Problema: Tre Liste Separate
โ SENZA Polimorfismo - Devi gestire tre liste
// Devi tenere tre liste separate:
private List<Automobile> listaAuto;
private List<AutoElettrica> listaElettriche;
private List<AutoSportiva> listaSportive;
// Tre foreach per aggiornare la ListBox:
foreach (Automobile a in listaAuto) lstAuto.Items.Add(a);
foreach (AutoElettrica e in listaElettriche) lstAuto.Items.Add(e);
foreach (AutoSportiva s in listaSportive) lstAuto.Items.Add(s);
// Tre cicli per salvare su file:
// ... idem ...
// ๐ฑ Il codice esplode di complessitร !
โ CON Polimorfismo - Una sola lista, tutto funziona
โ CON Polimorfismo - Elegante e semplice
// UNA SOLA lista di tipo Automobile
// ma puรฒ contenere anche AutoElettrica e AutoSportiva!
// Perchรฉ AutoElettrica e AutoSportiva SONO Automobile (ereditarietร )
private List<Automobile> listaAuto;
// Aggiungi tutti i tipi nella stessa lista:
listaAuto.Add(new Automobile("Fiat 500", 1200, "Benzina"));
listaAuto.Add(new AutoElettrica("Tesla Model 3", 500, 85));
listaAuto.Add(new AutoSportiva("Ferrari 488", 3900, "Benzina", 660, true));
// UN SOLO foreach per aggiornarla:
foreach (Automobile auto in listaAuto)
{
// C# chiama automaticamente il Stampa() GIUSTO per ogni oggetto!
// - Se รจ Automobile normale โ usa Automobile.Stampa()
// - Se รจ AutoElettrica โ usa AutoElettrica.Stampa() (override)
// - Se รจ AutoSportiva โ usa AutoSportiva.Stampa() (override)
lstAuto.Items.Add(auto); // ToString() โ Stampa() corretto!
}
// Risultato nella ListBox:
// Fiat 500 - 1200cc - Benzina
// Tesla Model 3 [โก Elettrica] - Autonomia: 500km - Batteria: 85%
// Ferrari 488 [๐๏ธ Sport][TURBO] - 3900cc - 660cv - Benzina
๐ฌ Come Funziona il Polimorfismo - Dietro le Quinte
// La lista contiene oggetti di tipo diverso, MA la variabile รจ Automobile:
Automobile auto = listaAuto[1]; // Prendo il secondo elemento
// Questo oggetto รจ in realtร un'AutoElettrica (era il Tesla)
// Ma C# SA che tipo รจ realmente (lo ricorda in memoria)
// Quando chiami Stampa()...
string testo = auto.Stampa();
// โ
// C# non chiama Automobile.Stampa()
// C# chiama AutoElettrica.Stampa() โ quello giusto!
//
// Questo si chiama DISPATCH DINAMICO:
// la versione del metodo da chiamare viene scelta
// a RUNTIME (mentre il programma gira) non a compilazione
// ร come se l'oggetto dicesse:
// "Sรฌ, mi chiami Automobile, ma io so CHI SONO davvero!"
๐ Riconoscere il Tipo Reale: is e as
A volte hai bisogno di sapere il tipo reale di un oggetto nella lista e accedere alle proprietร specifiche.
foreach (Automobile auto in listaAuto)
{
// "is" controlla se l'oggetto รจ di quel tipo
if (auto is AutoElettrica)
{
// "as" converte l'oggetto al tipo specifico
AutoElettrica elettrica = auto as AutoElettrica;
// Ora puoi accedere alle proprietร di AutoElettrica
MessageBox.Show($"Autonomia: {elettrica.AutonomiaKm}km");
}
else if (auto is AutoSportiva)
{
AutoSportiva sportiva = auto as AutoSportiva;
MessageBox.Show($"Potenza: {sportiva.CavalliVapore}cv");
}
else
{
// ร un'Automobile normale
MessageBox.Show($"Auto standard: {auto.Modello}");
}
}
Esempio Pratico: Aggiungere le Classi Figlie al Form
Vediamo come modificare il Form del Parco Auto per gestire anche
AutoElettrica e AutoSportiva con la stessa lista.
- Aggiungere una ComboBox per il Tipo di Auto
Aggiungi una ComboBox chiamata cmbTipoAuto con le voci:
"Standard", "Elettrica", "Sportiva".
Form1.cs - Inizializzazione
private void InizializzaTipiAuto()
{
cmbTipoAuto.Items.Add("Standard");
cmbTipoAuto.Items.Add("Elettrica");
cmbTipoAuto.Items.Add("Sportiva");
cmbTipoAuto.SelectedIndex = 0;
}
- Logica di Aggiunta: creare il tipo giusto in base alla scelta
Form1.cs - btnAggiungi_Click con Polimorfismo
private void btnAggiungi_Click(object sender, EventArgs e)
{
if (!ControllaCampi()) return;
if (!ValidaCilindrata(txtCilindrata.Text)) return;
string modello = txtModello.Text;
int cilindrata = Convert.ToInt32(txtCilindrata.Text);
string carburante = cmbCarburante.SelectedItem.ToString();
string tipoScelto = cmbTipoAuto.SelectedItem.ToString();
// Variabile di tipo BASE โ puรฒ contenere qualsiasi figlia
Automobile nuovaAuto;
// Crea il tipo giusto in base alla scelta dell'utente
if (tipoScelto == "Elettrica")
{
// Chiedi i dati specifici per l'elettrica
int autonomia = 400; // Potresti leggerli da una TextBox dedicata
int batteria = 100;
nuovaAuto = new AutoElettrica(modello, autonomia, batteria);
}
else if (tipoScelto == "Sportiva")
{
int cv = 300; // Anche questi da TextBox dedicate
bool turbo = false;
nuovaAuto = new AutoSportiva(modello, cilindrata, carburante, cv, turbo);
}
else
{
// Standard
nuovaAuto = new Automobile(modello, cilindrata, carburante);
}
// Aggiunge alla lista (polimorfismo: sempre List<Automobile>!)
listaAuto.Add(nuovaAuto);
// Aggiorna - funziona per TUTTI i tipi grazie al polimorfismo
AggiornaListaAuto();
AggiornaStatistiche();
PulisciCampi();
}
- Statistiche per Tipo - Usare
isper contare
Form1.cs - AggiornaStatistiche con tipi
private void AggiornaStatistiche()
{
int totale = listaAuto.Count;
int standard = 0;
int elettriche = 0;
int sportive = 0;
foreach (Automobile auto in listaAuto)
{
if (auto is AutoElettrica) elettriche++;
else if (auto is AutoSportiva) sportive++;
else standard++;
}
lblTotaleAuto.Text = $"Totale: {totale} " +
$"(Standard: {standard} | " +
$"โก Elettriche: {elettriche} | " +
$"๐๏ธ Sportive: {sportive})";
}
Schema Riassuntivo: Ereditarietร e Polimorfismo
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ AUTOMOBILE (Classe Base) โ
โ protected: _modello, _cilindrata, _carburante โ
โ public: Modello, Cilindrata, Carburante (proprietร ) โ
โ virtual: Stampa() โ puรฒ essere sostituito dalle figlie โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ eredita con ":"
โโโโโโโโโโโโโโโผโโโโโโโโโโโโโโ
โ โ โ
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
โAutoElettrica โ โ AutoSportiva โ โ AutoLusso โ
โ (figlia) โ โ (figlia) โ โ (figlia) โ
โ โ โ โ โ โ
โ +AutonomiaKm โ โ +CavalliVap. โ โ +Prezzo โ
โ +Batteria% โ โ +HasTurbo โ โ +Brand โ
โ +KmRimasti โ โ โ โ โ
โ โ โ โ โ โ
โ override โ โ override โ โ override โ
โ Stampa() โ โ Stampa() โ โ Stampa() โ
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
POLIMORFISMO in azione:
List<Automobile> lista = new List<Automobile>();
lista.Add(new Automobile(...)); // โ
Standard
lista.Add(new AutoElettrica(...)); // โ
Figlia accettata!
lista.Add(new AutoSportiva(...)); // โ
Figlia accettata!
foreach (Automobile a in lista)
{
lstAuto.Items.Add(a); // Chiama Stampa() GIUSTO per ognuno โ
}
REGOLA FONDAMENTALE:
"Una figlia PUร essere usata dove si aspetta il genitore"
AutoElettrica IS-A Automobile โ true โ
Automobile IS-A AutoElettrica โ false โ
๐ฏ Riepilogo: Tre Concetti in Tre Frasi
๐งฌ Ereditarietร
La classe figlia riceve gratis tutto quello che ha la classe genitore.
Aggiungi solo le parti nuove. Si scrive con : NomeGenitore.
class AutoElettrica : Automobile
{ /* eredita tutto! */ }
๐ Override
La figlia puรฒ riscrivere un metodo del genitore per adattarlo al suo caso.
Il genitore marca il metodo virtual, la figlia usa override.
public override string Stampa()
{ return "versione mia!"; }
๐ญ Polimorfismo
Puoi mettere tipi diversi nella stessa lista (di tipo base). Ogni oggetto risponde con il metodo giusto per il suo tipo.
List<Automobile> lista;
lista.Add(new AutoElettrica(...));
// funziona! โ
Riepilogo: Cosa Hai Imparato
1๏ธโฃ Ereditarietร
Le classi figlie ricevono gratis tutto il codice del genitore con
: NomeClasse. Scrivi meno, riusa di piรน: niente piรน codice duplicato!
2๏ธโฃ Override
Con
virtualnel genitore eoverridenella figlia, ogni classe puรฒ personalizzare un metodo mantenendo la stessa firma. Puoi anche richiamare l'originale conbase.Metodo().
3๏ธโฃ Polimorfismo
Una sola
List<Automobile>puรฒ contenereAutomobile,AutoElettrica,AutoSportiva. Ogni oggetto risponde con il metodo giusto per il suo tipo, automaticamente.
๐ Con le tre lezioni del Parco Auto hai imparato a progettare classi, rendere i dati permanenti e costruire gerarchie di classi: la base di qualsiasi applicazione seria.
Esercizi per Fare Pratica
๐ Parco Auto con Ereditarietร : la sfida!
- Parti dal progetto Parco Auto delle lezioni precedenti
- Crea la classe figlia
AutoElettricaconAutonomiaKmePercentualeBatteria- Crea la classe figlia
AutoSportivaconCavalliVaporeeHasTurbo- Overrida
Stampa()in entrambe per mostrare i dati specifici- Usa una sola
List<Automobile>per contenere tutti i tipi- Nelle statistiche, mostra il conteggio separato per tipo (
is)
๐ฑ Livello Base: Device Elettronici con suggerimenti
๐ก Suggerimento: Inizia con una classe base Device con marca, modello e prezzo
- Crea una classe base
Devicecon: Marca, Modello, Prezzo (virtual per calcolo sconto)- Crea classi derivate:
Smartphonecon SistemaOperativo e MemoriaGBTabletcon HasPenna e PolliciSchermoLaptopcon RamGB e Processore- ๐ Override del metodo
Descrizione()in ogni classe figlia- Aggiungi
CalcolaPrezzoScontato()nella base e overridalo in Smartphone (sconto 10%) e Laptop (sconto 15%)- Usa
List<Device>per gestire tutti i dispositivi
๐ฐ Livello Facile: App Pagamenti Digitali
๐ Ispirato a Satispay, PayPal, carte di credito
- Classe base
MetodoPagamentocon: Intestatario, Saldo- Classi derivate:
CartaCredito: Numero, Scadenza, CVV, MassimalePayPal: Email, CashbackPercentualeAppBancaria: IBAN, Banca, HasBiometricAuth- Override di
EseguiPagamento(decimal importo):
- CartaCredito: verifica massimale
- PayPal: applica cashback se importo > 50โฌ
- AppBancaria: richiede conferma biometrica
- ๐ฏ Extra: Override di
CalcolaCostoTransazione()diverso per ogni metodo
๐ Livello Intermedio: Casa Intelligente
๐ท๏ธ Dispositivi smart che comunicano come nella vita reale
- Classe base astratta
SmartDevicecon: Nome, Stanza, Stato, Consumo- Interfaccia
ITimerSupportper dispositivi con timer- Classi derivate:
LampadinaSmart: ColoreRGB, Luminositร , ITimerSupportTermostato: TemperaturaAttuale, TemperaturaTargetTapparellaElettrica: PercentualeApertura- Override obbligatorio di
EseguiComando(string comando)per ogni dispositivo- Gestisci tutto con
List<SmartDevice>(polimorfismo)
๐ต Livello Avanzato: App di Delivery
๐ฆ Ispirato a Glovo/JustEat - diversi tipi di consegna
- Classe base
Ordinecon: ID, Cliente, Indirizzo- Interfacce:
IConsegnaFrescoper catena del freddoIConsegnaUrgenteper consegne prioritarieITracciabileper tracking GPS- Classi con interfacce multiple:
OrdineCibo: TipoCucina, Temperatura โ IConsegnaFresco, IConsegnaUrgenteOrdineFarmacia: RicettaMedica โ IConsegnaUrgente, ITracciabileOrdineRegalo: Messaggio โ ITracciabile- Override di
CalcolaCostoConsegna()con regole diverse per ogni tipo- ๐ Challenge: Sistema di prioritร - ordini urgenti processati prima
๐ฎ Livello Esperto: Personaggi RPG
โ๏ธ Gerarchia complessa con override a catena
- Classe base astratta
Personaggiocon: Nome, Livello, PV, Mana- Metodi virtual:
Attacca(),Difendi(),UsaAbilita()- Gerarchia a 3 livelli:
- Liv1:
Guerriero,Mago,Arciere- Liv2:
Paladino(da Guerriero),Negromante(da Mago)- Liv3:
CavaliereDrago(da Paladino)- Override a catena con
base.Attacca()per accumulare bonus- Pattern Observer: quando un personaggio muore, tutti i nemici reagiscono
โญ BONUS: Gestione Dipendenti Aziendale
Simula ruoli aziendali con diverse regole di stipendio - Confronto tra didattica e realtร
- Classe base
Dipendente: Nome, Cognome, Matricola, Anzianitร - Classi derivate:
Impiegato: Livello, Straordinari (override stipendio con bonus)Manager: BudgetTeam, Progetti (override bonus progetti)Dirigente: StockOptions (override partecipazione utili)Stagista: Tutor, Durata (override stipendio = rimborso spese)
- Interfaccia
IConsulenteper chi lavora su progetti esterni - Override di
ToString()per riepilogo completo
CONFRONTO: Come funziona nel programma vs Come funziona davvero
| 1๏ธโฃ IMPIEGATO | ||
|---|---|---|
| Aspetto | Nel PROGRAMMA | Nella VITA REALE |
| Livello | Numero da 1 a 10 che dร 100โฌ in piรน al mese per ogni livello | ร il tuo inquadramento (es. apprendista, impiegato semplice, impiegato senior). Ogni livello ha uno stipendio minimo diverso stabilito dal contratto nazionale |
| Straordinari | 25โฌ per ogni ora, pagati subito nello stipendio del mese | Si pagano con una maggiorazione: +15% se sono in settimana, +30% se di sabato, +50% se di notte. Di solito li pagano il mese dopo |
| Calcolo | base + (livelloร100) + (straordinariร25) |
Minimo del contratto + aumenti per anzianitร + straordinari con percentuali |
| 2๏ธโฃ MANAGER | ||
|---|---|---|
| Aspetto | Nel PROGRAMMA | Nella VITA REALE |
| Budget Team | Prende il 5% del budget TUTTI I MESI | Il budget รจ per tutto l'anno. Il premio (bonus) lo riceve a fine anno se ha raggiunto gli obiettivi, e puรฒ essere dal 10% al 50% del suo stipendio annuale |
| Progetti | 500โฌ per ogni progetto finito, pagati subito | I progetti fanno parte degli obiettivi annuali. Non รจ "tot progetti fatti" ma "come li hai fatti" (rispettato tempi? budget? qualitร ?) |
| Esempio | Budget 100.000โฌ โ 5.000โฌ in piรน ogni mese (60.000โฌ in piรน all'anno di soli bonus) | Stipendio 50.000โฌ all'anno + premio 10.000โฌ a fine anno se obiettivi raggiunti |
| 3๏ธโฃ DIRIGENTE | ||
|---|---|---|
| Aspetto | Nel PROGRAMMA | Nella VITA REALE |
| Stock Options | ร solo un numero, non viene usato per calcolare lo stipendio | ร il diritto di comprare azioni della societร a un prezzo scontato. Se il valore delle azioni sale, puoi rivenderle e guadagnare la differenza |
| Utile Aziendale | Prende il 2% dell'utile TUTTI I MESI | L'utile si calcola sul bilancio di fine anno. Il dirigente riceve una percentuale sugli utili una volta all'anno |
| Esempio | Utile 2 milioni โ 40.000โฌ in piรน ogni mese (480.000โฌ in piรน all'anno) | Utile 2 milioni โ premio di 40.000โฌ una volta a fine anno |
| 4๏ธโฃ STAGISTA | ||
|---|---|---|
| Aspetto | Nel PROGRAMMA | Nella VITA REALE |
| Tutor | ร solo un nome associato allo stagista | ร la persona che segue lo stagista, gli insegna il lavoro, firma i documenti e alla fine lo valuta |
| Durata | Mesi di stage (da 1 a 6) | Di solito 3 o 6 mesi. A volte si puรฒ allungare. La legge dice quanto puรฒ durare al massimo |
| Rimborso | 600โฌ fissi al mese per tutti | Se รจ stage per scuola/universitร spesso non pagano. Se รจ stage dopo gli studi, danno un rimborso che puรฒ essere 300-800โฌ in base al contratto |
| 5๏ธโฃ CONSULENZA (chi lavora su progetti esterni) | ||
|---|---|---|
| Aspetto | Nel PROGRAMMA | Nella VITA REALE |
| Tariffa oraria | Moltiplica per le ore e paga subito | Chi fa consulenza di solito ha partita IVA. Emette fattura e viene pagato dopo 30-60-90 giorni, deve pagarci le tasse sopra |
LE DIFFERENZE PIร IMPORTANTI
| Concetto | Nel programma | Nella realtร |
|---|---|---|
| Premio per progetti | Pagato subito, ogni mese | Si valuta a fine anno |
| Percentuale sul budget | 5% tutti i mesi | Premio una volta all'anno se raggiungi obiettivi |
| Percentuale sugli utili | 2% tutti i mesi | Una volta all'anno a bilancio chiuso |
| Stock options | Solo un numero | Possibilitร di guadagnare in futuro se le azioni salgono |
PROGRAMMA
Il nostro codice รจ fatto per imparare a programmare, non per fare paghe vere. Serve a capire:
- Override - Come le classi figlie possono cambiare i metodi del padre
- Polimorfismo - Lo stesso metodo (
CalcolaStipendio()) funziona in modo diverso per ogni tipo- Incapsulamento - I dati sono protetti ma accessibili alle classi che servono
Se dovessimo fare un programma vero per paghe, sarebbe molto piรน complicato: bisognerebbe distinguere mensile da annuale, calcolare tasse, contributi, e mille altre cose. Ma per imparare l'ereditarietร e il polimorfismo, cosรฌ va benissimo!
Mappa dei Concetti negli Esercizi:
| Esercizio | Ereditarietร | Polimorfismo | Override | Extra |
|---|---|---|---|---|
| Device | โ Base | โ List | โ Virtual | Suggerimenti |
| Pagamenti | โ Singola | โ Metodi | โ Con logica | Contesto reale |
| Smart Home | โ Astratta | โ Comandi | โ Obbligatorio | Interfacce |
| Delivery | โ Multipla | โ Pattern | โ Complesso | Interfacce multiple |
| RPG | โ Multi-livello | โ Avanzato | โ A catena | Observer |
| Aziendale | โ Gerarchica | โ Oggetti | โ ToString | Mondo reale |
๐ฅ๏ธ Suggerimenti per l'Interfaccia Grafica:
- ComboBox per selezionare il tipo di oggetto da creare
- Campi che cambiano dinamicamente in base al tipo selezionato
- DataGridView con colonne specifiche usando polimorfismo
- Pannello statistiche che conta i tipi con 'is'
- Per RPG: barre della vita visive che si aggiornano
Prossimi Passi
Nelle Prossime Lezioni Imparerai:
- โก Eventi Multipli: Un solo metodo per gestire tanti controlli
- ๐ฏ Il Parametro sender: Scoprire QUALE controllo ha generato l'evento
- โ Validazione in Tempo Reale: Controllare mentre l'utente digita
- ๐จ Feedback Visivo: Cambiare colori per guidare l'utente
๐ฏ Scriverai codice piรน elegante e programmi piรน user-friendly!
โ Nelle tre lezioni del Parco Auto hai affrontato:
- ๐๏ธ Classi con campi
private/protectede proprietร con validazione- ๐ CRUD completo su
List<Automobile>- ๐พ Salvataggio e lettura da file TXT e CSV
- ๐ Ordinamento con
Sort()e lambda- ๐งฌ Ereditarietร con classi figlie (
: NomeClasse)- ๐ Override di metodi (
virtual+override+base)- ๐ญ Polimorfismo: una lista, tanti tipi, ogni oggetto risponde correttamente
๐ Teoria collegata (percorso C# โ il linguaggio, esempi in console): Ereditarietร , polimorfismo, classi astratte e interfacce.