Bonjour, homme Javarash. J'ai commencé à recevoir des questions sur la conversion de types de référence en Java. Afin de ne pas raconter à chaque fois la même chose, j’ai décidé d’écrire un petit article.
Tout d’abord, regardons ce qu’est le casting de type.
La conversion de type (conversion de type) est la conversion d’une valeur variable d’un type en une valeur d’un autre type. Regardons un exemple de ce que c'est et avec quoi on le mange. Nous avons une certaine hiérarchie de classes ( voir Figure 1 ). Ici vous pouvez voir toutes les classes de la hiérarchie, qui hérite de qui et les méthodes de chaque classe. Il y a une adduction en expansion et une contraction. Nous voyons que la classeCat
est un descendant de la classe Pet
. Pet
, à son tour, est un successeur de la classe Animal
. Quand on écrit :
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
Il s'agit d'un casting en expansion (ou implicite). Nous avons élargi les liens animalCat
et animalDog
. Ils font référence à des objets Cat
et Dog
. Avec un tel cast, nous ne pouvons pas animalCat/animalDog
appeler des méthodes via un lien qui sont dans Cat/Dog
, mais qui ne sont pas dans Animal
. Une distribution rétrécie (ou explicite) se produit dans la direction opposée :
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
Cat cat =(Cat)animalCat;
YorkshireTerrier dog = (YorkshireTerrier) animalDog;
Nous avons clairement indiqué vers quel type nous souhaitons convertir cet objet. MAIS FAIS ATTENTION!!! Si tu fais comme ça :
Animal animalCat = new Cat();
YorkshireTerrier dog = (YorkshireTerrier) animalCat;
le compilateur ignorera ce code. Mais RunTime
il vous lancera :
Exception in thread "main" java.lang.ClassCastException: Animals.Cat cannot be cast to Animals.YorkshireTerrier
RunTime
voit qu'il Cat
existe YorkshireTerrier
deux classes différentes. Pour éviter ClassCastException lors de la conversion restrictive, utilisez instanceof
.
Animal animalCat = new Cat();
if (animalCat instanceof YorkshireTerrier)
{
YorkshireTerrier dog = (YorkshireTerrier) animalCat;
}
Si animalCat
c'est le cas YorkshireTerrier
, alors l'affectation aura lieu, sinon, rien ne se passera.
Maintenant, pourquoi est-ce nécessaire si nous perdons des méthodes et pouvons obtenir de telles erreurs
Regardons le code que j'ai créé selon le schéma de la 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");
}
}
Une classe WildAnimal
qui hérite deAnimal
public abstract class WildAnimal extends Animal
{
public void steelChicken()
{
System.out.println(nameOfClass+": Muhaha,I stole a chicken!");
}
}
Une classe Pet
qui hérite deAnimal
public abstract class Pet extends Animal
{
public void peeInTray(){
System.out.println(nameOfClass + ": Master, I peed");
}
}
Une classe Fox
qui hérite deWildAnimal
public class Fox extends WildAnimal
{
public void eatColobok(){
System.out.println(nameOfClass + ": I will eat you, Colobok");
}
}
Une classe Wolf
qui hérite deWildAnimal
public class Wolf extends WildAnimal
{
public void hawlAtTheMoon(){
System.out.println(nameOfClass + ": Ouuuuu!!!Ouuuu!!!");
}
}
Une classe Cat
qui hérite dePet
public class Cat extends Pet
{
public void sleepOnKeyboard(){
System.out.println(nameOfClass + ": Master, stop working!!I wanna sleep on your keyboard");
}
}
Une classe YorkshireTerrier
qui hérite dePet
public class YorkshireTerrier extends Pet
{
public void bark(){
System.out.println(nameOfClass + ": Meow!!! Meow!!!");
}
}
Imaginez la situation. Nous devons rassembler tous les animaux sur une seule liste, les nourrir puis les mettre au lit. C'est facile à faire si nous créons ArrayList
des animaux ( Animal
). Et puis nous appelons les méthodes correspondantes pour chaque animal :
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();
}
}
}
Je ne peux pas animal
appeler la méthode bark()
ou sleepOnKeyboard()
. Car la feuille allAnimals
contient un chat, un loup, un yorick et un renard, mais ils sont réduits à Animal
. Et ils n'ont que les méthodes disponibles dans Animal
. C'est très bien, car si nous pouvions appeler toutes les méthodes, alors pourquoi avons-nous besoin d'un loup qui dort sur le clavier, ou d'un yorick qui vole des poulets ? Merci pour votre attention. J'espère que cet article vous sera utile. Les critiques et commentaires sont les bienvenus)
GO TO FULL VERSION