Good day, Javarash man. I started receiving questions about casting reference types in Java. In order not to retell the same thing every time, I decided to write a short article.
First, let's look at what type casting is.
Type casting (type conversion) is the conversion of a variable value of one type to a value of another type. Let's look at an example of what it is and what it is eaten with. We have some class hierarchy ( see Figure 1 ). Here you can see all the classes of the hierarchy, who inherits whom, and the methods of each class. There is an expanding and a contracting adduction. We see that the classCat
is a descendant of the class Pet
. Pet
, in turn, is a successor of the class Animal
. When we write:
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
This is an expanding cast (or an implicit one). We have expanded the links animalCat
and animalDog
. They refer to objects Cat
and Dog
. With such a cast, we cannot animalCat/animalDog
call methods through a link that are in Cat/Dog
, but which are not in Animal
. A narrowing (or explicit) cast occurs in the opposite direction:
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
Cat cat =(Cat)animalCat;
YorkshireTerrier dog = (YorkshireTerrier) animalDog;
We have clearly indicated what type we want to cast this object to. BUT, BE CAREFUL!!! If you do it like this:
Animal animalCat = new Cat();
YorkshireTerrier dog = (YorkshireTerrier) animalCat;
the compiler will skip this code. But RunTime
it will throw out to you:
Exception in thread "main" java.lang.ClassCastException: Animals.Cat cannot be cast to Animals.YorkshireTerrier
RunTime
sees that Cat
there are YorkshireTerrier
two different classes. To avoid ClassCastException during narrowing conversion, use instanceof
.
Animal animalCat = new Cat();
if (animalCat instanceof YorkshireTerrier)
{
YorkshireTerrier dog = (YorkshireTerrier) animalCat;
}
If animalCat
it is YorkshireTerrier
, then the assignment will occur, if not, nothing will happen.
Now why is this necessary if we lose methods and can get such errors
Let's look at the code that I made according to the diagram in Fig. 1 . ClassAnimal
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");
}
}
A class WildAnimal
that inherits fromAnimal
public abstract class WildAnimal extends Animal
{
public void steelChicken()
{
System.out.println(nameOfClass+": Muhaha,I stole a chicken!");
}
}
A class Pet
that inherits fromAnimal
public abstract class Pet extends Animal
{
public void peeInTray(){
System.out.println(nameOfClass + ": Master, I peed");
}
}
A class Fox
that inherits fromWildAnimal
public class Fox extends WildAnimal
{
public void eatColobok(){
System.out.println(nameOfClass + ": I will eat you, Colobok");
}
}
A class Wolf
that inherits fromWildAnimal
public class Wolf extends WildAnimal
{
public void hawlAtTheMoon(){
System.out.println(nameOfClass + ": Ouuuuu!!!Ouuuu!!!");
}
}
A class Cat
that inherits fromPet
public class Cat extends Pet
{
public void sleepOnKeyboard(){
System.out.println(nameOfClass + ": Master, stop working!!I wanna sleep on your keyboard");
}
}
A class YorkshireTerrier
that inherits fromPet
public class YorkshireTerrier extends Pet
{
public void bark(){
System.out.println(nameOfClass + ": Meow!!! Meow!!!");
}
}
Imagine the situation. We need to collect all the animals in one list, feed them and then put them to bed. This is easy to do if we create ArrayList
animals ( Animal
). And then we call the corresponding methods for each 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();
}
}
}
I can't animal
call the method bark()
or sleepOnKeyboard()
. Because the sheet allAnimals
contains a cat, a wolf, a yorick and a fox, but they are reduced to Animal
. And they only have the methods that are in Animal
. This is very good, because if we could call all the methods, then why do we need a wolf who sleeps on the keyboard, or a yorick who steals chickens? Thank you for your attention. I hope this article will be useful to you. Criticism and comments are welcome)
GO TO FULL VERSION