Buona giornata, Javarash. Ho iniziato a ricevere domande sui tipi di riferimento di casting in Java. Per non raccontare ogni volta la stessa cosa, ho deciso di scrivere un breve articolo.
Per prima cosa, diamo un'occhiata a che tipo di casting è.
Il casting del tipo (conversione del tipo) è la conversione di un valore variabile di un tipo in un valore di un altro tipo. Vediamo un esempio di cos'è e con cosa si mangia. Abbiamo una gerarchia di classi ( vedi Figura 1 ). Qui puoi vedere tutte le classi della gerarchia, chi eredita chi e i metodi di ciascuna classe. C'è un'adduzione in espansione e una in contrazione. Vediamo che la classeCat
è un discendente della classe Pet
. Pet
, a sua volta, è il successore della classe Animal
. Quando scriviamo:
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
Questo è un cast in espansione (o implicito). Abbiamo ampliato i collegamenti animalCat
e animalDog
. Si riferiscono a oggetti Cat
e Dog
. Con un cast di questo tipo, non possiamo animalCat/animalDog
chiamare metodi tramite un collegamento che si trova in Cat/Dog
, ma che non lo è Animal
. Un cast restringente (o esplicito) avviene nella direzione opposta:
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
Cat cat =(Cat)animalCat;
YorkshireTerrier dog = (YorkshireTerrier) animalDog;
Abbiamo indicato chiaramente a quale tipo vogliamo lanciare questo oggetto. MA FA ATTENZIONE!!! Se lo fai in questo modo:
Animal animalCat = new Cat();
YorkshireTerrier dog = (YorkshireTerrier) animalCat;
il compilatore salterà questo codice. Ma RunTime
ti dirà:
Exception in thread "main" java.lang.ClassCastException: Animals.Cat cannot be cast to Animals.YorkshireTerrier
RunTime
vede che Cat
ci sono YorkshireTerrier
due classi diverse. Per evitare ClassCastException durante la conversione restrittiva, utilizzare instanceof
.
Animal animalCat = new Cat();
if (animalCat instanceof YorkshireTerrier)
{
YorkshireTerrier dog = (YorkshireTerrier) animalCat;
}
Se animalCat
lo è YorkshireTerrier
, l'assegnazione avrà luogo, altrimenti non accadrà nulla.
Ora, perché è necessario se perdiamo metodi e possiamo ottenere tali errori
Diamo un'occhiata al codice che ho realizzato secondo lo schema in Fig. 1 . ClasseAnimal
public abstract class Animal
{
String name;
int age;
String nameOfClass = getClass().getSimpleName();
public void eat(){
System.out.println(nameOfClass + ": Omnomnom");
}
public void sleep(){
System.out.println(nameOfClass + ": Z-z-z-z");
}
}
Una classe WildAnimal
che eredita daAnimal
public abstract class WildAnimal extends Animal
{
public void steelChicken()
{
System.out.println(nameOfClass+": Muhaha,I stole a chicken!");
}
}
Una classe Pet
che eredita daAnimal
public abstract class Pet extends Animal
{
public void peeInTray(){
System.out.println(nameOfClass + ": Master, I peed");
}
}
Una classe Fox
che eredita daWildAnimal
public class Fox extends WildAnimal
{
public void eatColobok(){
System.out.println(nameOfClass + ": I will eat you, Colobok");
}
}
Una classe Wolf
che eredita daWildAnimal
public class Wolf extends WildAnimal
{
public void hawlAtTheMoon(){
System.out.println(nameOfClass + ": Ouuuuu!!!Ouuuu!!!");
}
}
Una classe Cat
che eredita daPet
public class Cat extends Pet
{
public void sleepOnKeyboard(){
System.out.println(nameOfClass + ": Master, stop working!!I wanna sleep on your keyboard");
}
}
Una classe YorkshireTerrier
che eredita daPet
public class YorkshireTerrier extends Pet
{
public void bark(){
System.out.println(nameOfClass + ": Meow!!! Meow!!!");
}
}
Immagina la situazione. Dobbiamo raccogliere tutti gli animali in un elenco, dar loro da mangiare e poi metterli a letto. Questo è facile da fare se creiamo ArrayList
animali ( Animal
). E poi chiamiamo i metodi corrispondenti per ciascun animale:
public class ZOO
{
public static void main(String[] args)
{
List<Animal> allAnimals = new ArrayList<>();
allAnimals.add(new Cat());
allAnimals.add(new Wolf());
allAnimals.add(new Fox());
allAnimals.add(new YorkshireTerrier());
for (Animal animal : allAnimals)
{
animal.eat();
animal.sleep();
}
}
}
Non posso animal
chiamare il metodo bark()
o sleepOnKeyboard()
. Perché il foglio allAnimals
contiene un gatto, un lupo, uno yorick e una volpe, ma sono ridotti a Animal
. E hanno solo i metodi in Animal
. Questo è molto positivo, perché se potessimo nominare tutti i metodi, allora perché avremmo bisogno di un lupo che dorme sulla tastiera o di uno yorick che ruba le galline? Grazie per l'attenzione. Spero che questo articolo ti sarà utile. Sono gradite critiche e commenti)
GO TO FULL VERSION