Guten Tag, Javarash-Mann. Ich erhielt erstmals Fragen zum Casting von Referenztypen in Java. Um nicht jedes Mal das Gleiche zu erzählen, habe ich beschlossen, einen kurzen Artikel zu schreiben.
Schauen wir uns zunächst an, um welche Art von Casting es sich handelt.
Typumwandlung (Typkonvertierung) ist die Umwandlung eines Variablenwerts eines Typs in einen Wert eines anderen Typs. Schauen wir uns ein Beispiel an, was es ist und womit es gegessen wird. Wir haben eine gewisse Klassenhierarchie ( siehe Abbildung 1 ). Hier sehen Sie alle Klassen der Hierarchie, wer wen erbt und die Methoden jeder Klasse. Es gibt eine expandierende und eine kontrahierende Adduktion. Wir sehen, dass die KlasseCat
ein Nachkomme der Klasse ist Pet
. Pet
wiederum ist ein Nachfolger der Klasse Animal
. Wenn wir schreiben:
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
Dies ist eine expandierende Besetzung (oder eine implizite). animalCat
Wir haben die Links und erweitert animalDog
. Sie beziehen sich auf Objekte Cat
und Dog
. Mit einer solchen Umwandlung können wir animalCat/animalDog
über einen Link keine Methoden aufrufen, die in sind Cat/Dog
, aber nicht in Animal
. Eine einschränkende (oder explizite) Umwandlung erfolgt in die entgegengesetzte Richtung:
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
Cat cat =(Cat)animalCat;
YorkshireTerrier dog = (YorkshireTerrier) animalDog;
Wir haben klar angegeben, in welchen Typ wir dieses Objekt umwandeln möchten. ABER SEI VORSICHTIG!!! Wenn Sie es so machen:
Animal animalCat = new Cat();
YorkshireTerrier dog = (YorkshireTerrier) animalCat;
Der Compiler überspringt diesen Code. Aber RunTime
es wird dir rauswerfen:
Exception in thread "main" java.lang.ClassCastException: Animals.Cat cannot be cast to Animals.YorkshireTerrier
RunTime
sieht, dass es zwei verschiedene Klassen Cat
gibt . YorkshireTerrier
Um ClassCastException während der einschränkenden Konvertierung zu vermeiden, verwenden Sie instanceof
.
Animal animalCat = new Cat();
if (animalCat instanceof YorkshireTerrier)
{
YorkshireTerrier dog = (YorkshireTerrier) animalCat;
}
Wenn animalCat
dies der Fall ist YorkshireTerrier
, erfolgt die Zuweisung, andernfalls geschieht nichts.
Warum ist das nun notwendig, wenn wir Methoden verlieren und solche Fehler bekommen können?
Schauen wir uns den Code an, den ich gemäß dem Diagramm in Abb. erstellt habe. 1 . KlasseAnimal
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");
}
}
Eine Klasse WildAnimal
, die erbt vonAnimal
public abstract class WildAnimal extends Animal
{
public void steelChicken()
{
System.out.println(nameOfClass+": Muhaha,I stole a chicken!");
}
}
Eine Klasse Pet
, die erbt vonAnimal
public abstract class Pet extends Animal
{
public void peeInTray(){
System.out.println(nameOfClass + ": Master, I peed");
}
}
Eine Klasse Fox
, die erbt vonWildAnimal
public class Fox extends WildAnimal
{
public void eatColobok(){
System.out.println(nameOfClass + ": I will eat you, Colobok");
}
}
Eine Klasse Wolf
, die erbt vonWildAnimal
public class Wolf extends WildAnimal
{
public void hawlAtTheMoon(){
System.out.println(nameOfClass + ": Ouuuuu!!!Ouuuu!!!");
}
}
Eine Klasse Cat
, die erbt vonPet
public class Cat extends Pet
{
public void sleepOnKeyboard(){
System.out.println(nameOfClass + ": Master, stop working!!I wanna sleep on your keyboard");
}
}
Eine Klasse YorkshireTerrier
, die erbt vonPet
public class YorkshireTerrier extends Pet
{
public void bark(){
System.out.println(nameOfClass + ": Meow!!! Meow!!!");
}
}
Stellen Sie sich die Situation vor. Wir müssen alle Tiere in einer Liste sammeln, sie füttern und dann ins Bett bringen. ArrayList
Dies ist einfach, wenn wir Tiere erstellen ( Animal
). Und dann rufen wir für jedes Tier die entsprechenden Methoden auf:
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();
}
}
}
animal
Ich kann die Methode bark()
oder nicht aufrufen sleepOnKeyboard()
. Denn das Blatt allAnimals
enthält eine Katze, einen Wolf, einen Yorick und einen Fuchs, die aber auf reduziert sind Animal
. Und sie verfügen nur über die Methoden, die in enthalten sind Animal
. Das ist sehr gut, denn wenn wir alle Methoden aufrufen könnten, warum brauchen wir dann einen Wolf, der auf der Tastatur schläft, oder einen Yorick, der Hühner stiehlt? Vielen Dank für Ihre Aufmerksamkeit. Ich hoffe, dass dieser Artikel für Sie nützlich sein wird. Kritik und Kommentare sind willkommen)
GO TO FULL VERSION