back to top

Ereditarietà in Java

In questo articolo, approfondiremo un concetto fondamentale della programmazione orientata agli oggetti in Java: l’ereditarietà. Comprendere l’ereditarietà è cruciale per scrivere codice efficace e riutilizzabile, in quanto consente di creare classi derivate che estendono le funzionalità delle classi base.

Cos’è l’Ereditarietà in Java?

L’ereditarietà in Java permette di riutilizzare il codice definito in una classe esistente (classe base o superclasse) in una nuova classe (classe derivata o sottoclasse). In altre parole, possiamo ereditare attributi e metodi da una classe esistente e, se necessario, aggiungere nuovi comportamenti o stati specifici della sottoclasse.

Pubblicità

Esempio di Ereditarietà

Consideriamo il seguente esempio di una classe base chiamata Dipendente:

public class Dipendente {
  public String nome;
  public String cognome;
  public int stipendio;  
}

Supponiamo di voler creare una classe per i dipendenti che sono anche responsabili di un progetto. Qui, la classe Dipendente sarà estesa utilizzando la parola chiave extends. La nostra nuova classe DipendenteResponsabile avrà un attributo aggiuntivo per rappresentare il progetto di cui è responsabile:

public class DipendenteResponsabile extends Dipendente {
  public String progetto;  
}

Con questa estensione, DipendenteResponsabile eredita gli attributi nome, cognome, e stipendio dalla classe Dipendente, aggiungendo l’attributo progetto.

Vantaggi dell’Ereditarietà

Un modo efficace per comprendere i vantaggi dell’ereditarietà è considerare le complessità e i cambiamenti futuri nelle classi. Immaginiamo di avere diverse figure professionali nell’azienda: Dipendente, ResponsabileProgetto, ResponsabileSettore e Direttore. Senza l’ereditarietà, dovremmo creare e gestire quattro classi distinte, anche se condividono molti attributi in comune. Se decidiamo di aggiungere attributi come la data di nascita o la data di assunzione, saremmo costretti a modificare ogni singola classe. Con l’ereditarietà, possiamo semplicemente aggiornare la classe Dipendente, e tutte le classi che la estendono beneficeranno delle modifiche automaticamente. Questo approccio rende la manutenzione del codice molto più semplice ed efficiente, specialmente in progetti di grandi dimensioni.

L’Incapsulamento e l’Ereditarietà

È importante notare che quando estendiamo una classe, non tutti gli attributi e metodi vengono ereditati. Vengono ereditati solo quelli dichiarati public. Se gli attributi sono dichiarati come private, non saranno direttamente accessibili nella sottoclasse. Pertanto, è buona pratica dichiarare i metodi che gestiscono gli attributi come pubblici. Questo permette di accedere e manipolare gli attributi della superclasse anche nella sottoclasse. Così, l’incapsulamento e l’ereditarietà possono coesistere senza problemi all’interno del nostro codice.

Considerazioni sull’Ereditarietà

Ricordiamo che l’ereditarietà può essere utilizzata sempre, ma è fondamentale chiedersi se l’approccio ha senso dal punto di vista logico. Ad esempio, se abbiamo una classe Dipendente con attributi come nome e cognome, e vogliamo creare una classe Fornitore che include prezzi, estendere la classe Dipendente sarebbe un errore logico. In questo caso, è preferibile definire una classe Fornitore separata. Pertanto, prima di estendere una classe, dobbiamo sempre porci la domanda: … è un …?

  • Un fornitore è un dipendente? No, quindi non estendo la classe Dipendente; creerò una classe Fornitore a parte.
  • Il responsabile pubblicitario dell’azienda è un dipendente? Sì, quindi estenderò la classe Dipendente, aggiungendo l’attributo per il budget pubblicitario mensile.

Ereditarietà e Classe Object

In Java, ogni classe, anche se non esplicitamente dichiarata, estende sempre la classe base Object. Questo significa che qualsiasi classe creata avrà accesso alle funzionalità di Object. Ad esempio, il seguente codice non genererà errori di compilazione:

public class Dipendente extends Object {

}

Se omettiamo la parte extends Object, il compilatore lo aggiunge automaticamente, conferendo alla classe Dipendente le funzionalità di base fornite da Object.

Pubblicità