"Ciao, Amigo! L'argomento della lezione di oggi è l'allargamento e il restringimento delle conversioni di tipo. Hai imparato a ampliare e restringere i tipi primitivi molto tempo fa. Al livello 10. Oggi parleremo di come funziona per i tipi di riferimento, ad es. istanze di classi”.
In effetti, è tutto abbastanza semplice. Immagina la catena di ereditarietà di una classe: la classe, il suo genitore, il genitore del genitore, ecc., fino alla classe Object. Poiché una classe contiene tutti i metodi membro della classe che eredita , un'istanza della classe può essere salvata in una variabile il cui tipo è quello di uno dei suoi genitori.
Ecco un esempio:
Codice | Descrizione |
---|---|
|
Qui abbiamo tre dichiarazioni di classe: Animale, Gatto e Tigre. Il gatto eredita l'animale. E Tiger eredita Cat. |
|
Un oggetto Tiger può sempre essere assegnato a una variabile il cui tipo è quello di uno dei suoi predecessori. Per la classe Tigre, questi sono Gatto, Animale e Oggetto. |
Ora diamo un'occhiata all'allargamento e al restringimento delle conversioni.
Se un'operazione di assegnazione ci fa risalire la catena di ereditarietà (verso la classe Object), allora abbiamo a che fare con una conversione di ampliamento (nota anche come upcasting). Se ci spostiamo lungo la catena verso il tipo di oggetto, si tratta di una conversione restringente (nota anche come downcasting).
Lo spostamento verso l'alto della catena di ereditarietà si chiama ampliamento, perché porta a un tipo più generale. Tuttavia, così facendo perdiamo la possibilità di invocare i metodi aggiunti alla classe attraverso l'ereditarietà.
Codice | Descrizione |
---|---|
|
Quando si restringe il tipo, è necessario utilizzare un operatore di conversione del tipo, ovvero eseguiamo una conversione esplicita.
Ciò fa sì che la macchina Java controlli se l'oggetto eredita davvero il tipo in cui vogliamo convertirlo. Questa piccola innovazione ha prodotto una molteplice riduzione del numero di errori di casting del tipo e ha aumentato significativamente la stabilità dei programmi Java. |
Codice | Descrizione |
---|---|
|
Meglio ancora, usa un'istanza di check |
|
Ed ecco perché. Dai un'occhiata all'esempio a sinistra.
Noi (il nostro codice) non sempre sappiamo con che tipo di oggetto stiamo lavorando. Potrebbe essere un oggetto dello stesso tipo della variabile (Animale) o qualsiasi tipo discendente (Gatto, Tigre). Considera il metodo doAllAction. Funziona correttamente, indipendentemente dal tipo di oggetto passato. In altre parole, funziona correttamente per tutti e tre i tipi: Animale, Gatto e Tigre. |
|
Qui abbiamo tre operazioni di assegnazione. Sono tutti esempi di conversioni in espansione.
L'operatore type cast non è necessario qui, perché non è necessario alcun controllo. Un riferimento a un oggetto può sempre essere memorizzato in una variabile il cui tipo è uno dei suoi predecessori. |
"Oh, il penultimo esempio ha chiarito tutto: perché è necessario il controllo e perché è necessario il casting del tipo."
"Lo spero. Voglio attirare la tua attenzione su questo fatto:"
Niente di tutto ciò fa cambiare un oggetto in alcun modo! L'unica cosa che cambia è il numero di metodi disponibili per essere chiamati su una particolare variabile di riferimento.
Ad esempio, una variabile Cat consente di chiamare i metodi doAnimalActions e doCatActions. Non sa nulla del metodo doTigerActions, anche se punta a un oggetto Tiger.
"Sì, ho capito. È stato più facile di quanto pensassi."
GO TO FULL VERSION