Creative Saplings

Ereditarietà

Settembre 6, 2020
No Comments

Nelle lezioni precedenti, hai visto l’ereditarietà menzionata più volte. Nel linguaggio Java, le classi possono essere derivate da altre classi, ereditando così campi e metodi da quelle classi.

Definizioni: una classe derivata da un’altra classe è chiamata sottoclasse (anche una classe derivata, estesa classe o classe figlio). La classe da cui deriva la sottoclasse è chiamata superclasse (anche una classe base o una classe genitore).
Ad eccezione di Object, che non ha superclasse, ogni classe ne ha una e solo una superclasse diretta (eredità singola). In assenza di qualsiasi altra superclasse esplicita, ogni classe è implicitamente una sottoclasse di Object.
Le classi possono essere derivate da classi derivate da classi derivate da classi e così via, e in definitiva derivato dalla classe più in alto, Object. Si dice che una tale classe discenda da tutte le classi nella catena di ereditarietà che risale a Object.

L’idea dell’ereditarietà è semplice ma potente: quando vuoi creare una nuova classe ed esiste già una classe che include parte del codice che desideri, puoi derivare la tua nuova classe dalla classe esistente . In questo modo, puoi riutilizzare i campi e i metodi della classe esistente senza doverli scrivere (ed eseguire il debug!).

Una sottoclasse eredita tutti i membri (campi, metodi e classi nidificate) da la sua superclasse. I costruttori non sono membri, quindi non vengono ereditati dalle sottoclassi, ma il costruttore della superclasse può essere richiamato dalla sottoclasse.

Gerarchia delle classi della piattaforma Java

Il Object, definita nel pacchetto java.lang, definisce e implementa il comportamento comune a tutte le classi, comprese quelle che scrivi. Nella piattaforma Java, molte classi derivano direttamente da Object, altre derivano da alcune di queste classi e così via, formando una gerarchia di classi.

Tutte le classi nella piattaforma Java sono discendenti di oggetti

In cima alla gerarchia, Object è la più generale di tutte le classi. Le classi nella parte inferiore della gerarchia forniscono un comportamento più specializzato.

Un esempio di ereditarietà

Di seguito è riportato il codice di esempio per una possibile implementazione di un Bicycle che è stata presentata nella lezione Classi e oggetti:

Una dichiarazione di classe per una classe MountainBike che è una sottoclasse di Bicycle potrebbe avere questo aspetto:

public class MountainBike extends Bicycle { // the MountainBike subclass adds one field public int seatHeight; // the MountainBike subclass has one constructor public MountainBike(int startHeight, int startCadence, int startSpeed, int startGear) { super(startCadence, startSpeed, startGear); seatHeight = startHeight; } // the MountainBike subclass adds one method public void setHeight(int newValue) { seatHeight = newValue; } }

MountainBike eredita tutti i campi e i metodi di Bicycle e aggiunge il campo seatHeight e un metodo per impostarlo. Ad eccezione del costruttore, è come se avessi scritto una nuova classe MountainBike interamente da zero, con quattro campi e cinque metodi. Tuttavia, non dovevi fare tutto il lavoro. Ciò sarebbe particolarmente utile se i metodi nella classe Bicycle fossero complessi e avessero richiesto molto tempo per il debug.

Cosa puoi fare in una sottoclasse

Una sottoclasse eredita tutti i membri pubblici e protetti del suo genitore, indipendentemente dal pacchetto in cui si trova la sottoclasse. Se la sottoclasse è nello stesso pacchetto della sua genitore, eredita anche i membri privati del pacchetto del genitore. Puoi utilizzare i membri ereditati così come sono, sostituirli, nasconderli o completarli con nuovi membri:

  • I campi ereditati possono essere utilizzato direttamente, proprio come qualsiasi altro campo.
  • Puoi dichiarare un campo nella sottoclasse con lo stesso nome di quello nella superclasse, nascondendolo (sconsigliato).
  • Puoi dichiarare nuovi campi nella sottoclasse che non sono nella superclasse.
  • I metodi ereditati possono essere utilizzati direttamente così come sono.
  • Puoi scrivere un nuovo metodo di istanza nel sottoclasse quello ha la stessa firma di quella nella superclasse, quindi sovrascrivendola.
  • Puoi scrivere un nuovo metodo statico nella sottoclasse che abbia la stessa firma di quello nella superclasse, nascondendolo così.
  • Puoi dichiarare nuovi metodi nella sottoclasse che non sono nella superclasse.
  • Puoi scrivere un costruttore di sottoclassi che invoca il costruttore della superclasse, sia implicitamente che usando la parola chiave super.

Le seguenti sezioni di questa lezione si espanderanno su questi argomenti.

Membri privati in una Superclasse

Una sottoclasse non eredita i private membri della sua classe genitore. Tuttavia, se la superclasse ha metodi pubblici o protetti per accedere ai suoi campi privati, questi possono essere utilizzati anche dalla sottoclasse.

Una classe annidata ha accesso a tutti i membri privati della sua classe che la racchiude, sia campi che metodi. Pertanto, una classe nidificata pubblica o protetta ereditata da una sottoclasse ha accesso indiretto a tutti i membri privati della superclasse.

Casting di oggetti

Abbiamo visto che un oggetto è del tipo di dati della classe da cui è stata creata un’istanza. Ad esempio, se scriviamo

public MountainBike myBike = new MountainBike();

allora myBike è di tipo MountainBike.

MountainBike discende da Bicycle e Object. Pertanto, un MountainBike è un Bicycle ed è anche un Object e può essere utilizzato ovunque siano richiesti oggetti Bicycle o Object.

Non è necessariamente vero il contrario: a Bicycle può essere un MountainBike, ma non lo è “necessariamente. Allo stesso modo, un Object può essere un Bicycle o MountainBike, ma non lo è necessariamente.

Il casting mostra l’uso di un oggetto di uno tipo al posto di un altro tipo, tra gli oggetti consentiti dall’ereditarietà e dalle implementazioni. Ad esempio, se scriviamo

Object obj = new MountainBike();

allora obj è sia un Object e un MountainBike (fino a quando obj non viene assegnato un altro oggetto che non è un MountainBike). Questo è chiamato casting implicito.

Se, d’altra parte, scriviamo

MountainBike myBike = obj;

lo faremmo riceve un errore in fase di compilazione perché obj non è noto al compilatore come MountainBike. Tuttavia, possiamo dire al compilatore che promettiamo di assegnare un MountainBike a obj tramite casting esplicito:

MountainBike myBike = (MountainBike)obj;

Questo cast inserisce un controllo di runtime che a obj sia assegnato un MountainBike in modo che il compilatore possa tranquillamente presumere che obj sia un MountainBike. Se obj non è un MountainBike in fase di esecuzione, verrà generata un’eccezione.

Nota: puoi creare un verifica logica del tipo di un particolare oggetto utilizzando l’operatore instanceof. Questo può salvarti da un errore di runtime dovuto a un cast improprio. Ad esempio:

if (obj instanceof MountainBike) { MountainBike myBike = (MountainBike)obj;}

Qui l’operatore instanceof verifica che obj si riferisce a un MountainBike in modo che possiamo eseguire il cast con la consapevolezza che non verrà generata alcuna eccezione di runtime.

Articles
Previous Post

5 cose che devi fare quando dipingi mobili di bianco

Next Post

Mal di testa e dolore agli occhi: cause e trattamento

Lascia un commento Annulla risposta

Articoli recenti

  • Best Photography Schools In The World, 2020
  • I cittadini sovrani portano la loro filosofia antigovernativa sulle strade
  • Guida ai costi di riparazione dello stucco
  • Muckrakers (Italiano)
  • Oncologia di precisione

Archivi

  • Febbraio 2021
  • Gennaio 2021
  • Dicembre 2020
  • Novembre 2020
  • Ottobre 2020
  • Settembre 2020
  • Deutsch
  • Nederlands
  • Svenska
  • Norsk
  • Dansk
  • Español
  • Français
  • Português
  • Italiano
  • Română
  • Polski
  • Čeština
  • Magyar
  • Suomi
  • 日本語
  • 한국어
Proudly powered by WordPress | Theme: Fmi by Forrss.