Last Updated on 2 anni | Published: 18/04/2024
Principio dell' Ereditarietà
L’ ereditarietà è uno dei principi fondamentali della Programmazione Orientata agli Oggetti (OOP) che consente di creare nuove classi basate su classi esistenti, ereditando le loro proprietà (attributi) e comportamenti (metodi). In questo articolo, esploreremo il concetto di ereditarietà in Java, iniziando dalle spiegazioni di base per poi approfondire concetti più avanzati.
L’ ereditarietà è il processo attraverso il quale una nuova classe (chiamata sottoclasse o classe derivata) può ereditare attributi e metodi da una classe esistente (chiamata superclasse o classe base). Questo principio consente di creare una gerarchia di classi che rappresentano una relazione “è-un” tra gli oggetti, dove la sottoclasse è un tipo specifico della superclasse.
Nel contesto della programmazione OOP, l’ ereditarietà permette di riutilizzare il codice esistente, promuovendo la modularità, l’estensibilità e la manutenibilità del codice. Inoltre, facilita la progettazione e l’implementazione di sistemi software che rappresentano efficacemente le relazioni e le gerarchie di classi nel dominio del problema.
Per definire una classe derivata in Java, si utilizza la parola chiave extends seguita dal nome della classe base.
public class Veicolo {
// Metodo della classe base
public void accendi() {
System.out.println(“Il veicolo è stato acceso.“);
}
// Metodo della classe base
public void spegni() {
System.out.println(“Il veicolo è stato spento.“);
}
}
// Metodo della classe derivata
public void guida() {
System.out.println(“L’auto si muove.“);
}
}
public class TestEreditarieta {
public static void main(String[] args) {
// Creazione di un oggetto della classe derivata Auto
Auto miaAuto = new Auto();
// Chiamata ai metodi ereditati dalla classe base Veicolo
miaAuto.accendi();
// Output: Il veicolo è stato acceso.
miaAuto.spegni();
// Output: Il veicolo è stato spento.
// Chiamata al metodo della classe derivata Auto
miaAuto.guida(); // Output: L’auto si muove.
}
}
- La classe
Veicoloè la classe base che definisce due metodiaccendi()espegni(). - La classe
Autoè la classe derivata che estende la classe baseVeicoloed eredita i suoi metodi. - La classe
TestEreditarietaè una classe di prova che contiene il metodomainper creare un oggetto della classeAutoe chiamare i metodi ereditati e il metodo specifico della classeAuto.
Un esempio semplice potrebbe riguardare la modellazione di diverse tipologie di prodotti in un negozio di elettronica. Immaginiamo di avere una classe Prodotto base e due sottoclassi Cellulari e Computer. Ecco come potrebbe essere implementato:
// Creazione di un oggetto Smartphone
// stampando l’ oggetto ottengo lo stato degli attributi
System.out.println(apple);
System.out.println(acer);
}
}
In Java, una classe può estendere una sola classe base alla volta, seguendo il principio dell’ ereditarietà singola. Questa scelta di progettazione è stata fatta per evitare le complessità e le ambiguità che potrebbero emergere dall’ereditarietà multipla.
L’ ereditarietà multipla, che permette a una classe di estendere più di una classe base, può portare a problemi di ambiguità e conflitti. Ad esempio, se due classi base forniscono metodi con la stessa firma (nome e parametri), potrebbe sorgere la domanda su quale metodo ereditare e come gestire eventuali conflitti.
Ereditarietà multiple
In Java, l’ ereditarietà multipla delle classi non è direttamente supportata. Tuttavia, è possibile simulare un certo tipo di ereditarietà multipla utilizzando le interfacce. Di seguito, un esempio semplice che illustra come una classe Uccello possa implementare due interfacce, Animale e Volante, per ereditare metodi da entrambe.
void vola();
}
void mangia();
}
@Override
public void mangia() {
System.out.println(“L’uccello mangia.“);
} @Override
public void vola() {
System.out.println(“L’uccello vola.“);
}
public void canta() {
System.out.println(“L’uccello canta.“);
}
}
// Classe di prova con il metodo main
public class TestEreditarietaMultipla {
// Creazione di un oggetto della classe Uccello
Uccello mioUccello = new Uccello();
// Chiamata al metodo ereditato dall’interfaccia Animale
mioUccello.mangia(); // Output: L’uccello mangia.
// Chiamata al metodo ereditato dall’interfaccia Volante
mioUccello.vola(); // Output: L’uccello vola.
// Chiamata al metodo della classe Uccello
mioUccello.canta(); // Output: L’uccello canta.
}
}
Ereditarietà e Override dei metodi
Il principio dell’ Override dei metodi consente alle classi derivate di fornire una specifica implementazione di un metodo ereditato dalla classe base, permettendo una maggiore flessibilità e polimorfismo nel design delle applicazioni. Di seguito un semplice esempio:
public class Veicolo {
public void descrizione() {
System.out.println(“Veicolo Trasporto Persone“);
}
}
Nell’esempio fornito, abbiamo una classe base Veicolo con un metodo descrizione(). La classe derivata Auto eredita il metodo descrizione() e lo modifica usando l’annotazione @Override. Questa annotazione è utilizzata per indicare che il metodo nella classe derivata sta sovrascrivendo un metodo della classe base. Quando si chiama il metodo descrizione() su un oggetto di tipo Auto, viene eseguito il metodo definito nella classe Auto, anche se l’oggetto è dichiarato come tipo Veicolo.
Nel prossimo articolo parleremo delle classi astratte che rappresentano un concetto fondamentale della programmazione OOP e servono come base per creare altre classi ………
