This article is a continuation of "Upcast (Java) that can reduce the amount of change when the specification is changed". Therefore, some source code (Cat class, Dog class, Life_form class) etc. are listed in the "Source code" item at the bottom.
The text starts with "What is a downcast?"
Atom : 1.28.0 Electron: 2.0.3 Chrome : 61.0.3163.100 Node : 8.9.3
java version "1.8.0_161" Java(TM) SE Runtime Environment (build 1.8.0_161-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.161-b12, mixed mode)
In "Upcast (Java) that can reduce the amount of change when specifications are changed", upcast was dealt with, but the opposite operation is called downcast.
But don't put it together so easily.
The upcast was a safe type conversion. Since the child class inherits from the parent class, it has all the fields and functions of the parent class. So even if you assign (upcast) a child class to an instance of the parent class, it makes sense to work fine.
But downcasting doesn't work that way. The parent class does not have its own functions in the child class. ** It would be a bit strange to declare a child class but not have the functions and fields that the child class should have. ** **
In fact, when I try to downcast, the compiler gets angry like this.
Main.java
public class Main{
public static void main(String[] args){
//Downcast
Cat cat = new Life_form(); //Subclass <-Super class
cat.makeSound();
}
}
When I try to downcast (assign the parent class Life_form to the child class Cat), the compiler points out that the types are incompatible.
Then how about this (↓)?
Main.java
//Subclass <-Super class
public class Main{
public static void main(String[] args){
Life_form life_form = new Life_form();
Cat cat = new Cat();
//Downcast
cat = (Cat)life_form; //Subclass <-Super class
cat.makeSound();
}
}
If you forcibly cast it like the above program, the compilation will pass. But this time I get a run-time error.
Exception in thread "main" java.lang.ClassCastException: Life_form cannot be cast to Cat at Main.main(Main.java:31)
After all it is pointed out that the type is incompatible.
Then what should I do?
In fact, downcasts are not used directly like upcasts. ** In a downcast, the entity of the superclass instance must be a subclass **. In other words, the parent class cannot be put into the child class as it is.
All you have to do is instantiate the superclass in a subclass and downcast it, as in the code below.
Main.java
public class Main{
public static void main(String[] args){
//Upcast
Life_form life_form = new Cat(); //Super class <-subclass
//Downcast
Cat cat = (Cat)life_form; //Subclass <-Super class
cat.catPunch();
}
}
If you write it like this, you can execute it properly. Note that you need to ** cast it properly (Cat) **.
Downcasts are closely related to upcasts, so let's review a little.
I want to use a class A instance as a function argument, but I also want to specify a class B instance. Upcast was used in such situations.
When Cat is upcast to Life_fome, the entity of Life_form is an instance of Cat class, and Cat class overrides makeSound () function.
life_form.makeSound();
The result of executing is makeSound () of Cat class.
However, the Cat class-specific function catPunch () cannot be called. ** Even if the entity is Cat, it implicitly behaves as Life_form **.
When I run catPunch () in the upcast state, it is pointed out like this.
<img width="327" alt="スクリーンショット 2018-07-02 18.08.36.png " src="https://qiita-image-store.s3.amazonaws.com/0/219573/f3849dd4-54b7-fd94-b1d1-83d70296533c.png ">
Even though life_form is instantiated in Cat, it is pointed out that "symbol not found" because life_form implicitly behaves as a parent class.
#### So how do you call catPunch ()?
It's easy. You can downcast it.
If you look at the code in the "Success example" section and its execution result, you can confirm that catPunch () is available.
Remember that downcasting is used when you want to use a function that is unique to each instance **.
# Summary
--Downcast will be used for upcast ones.
--Use when you want to use an upcast child class instance-specific function.
# Source code
Details of the classes used in this article.
#### **`Life_form.java`**
```java
//Parent class
public class Life_form{
public void makeSound(){
System.out.println("???");
}
}
Cat.java
//Child class
public class Cat extends Life_form{
@Override
public void makeSound(){
System.out.println("nyaa");
}
public void catPunch(){
System.out.println("Cat bread");
}
}
Dog.java
//It is used in the item "Please change the specifications".
public class Dog extends Life_form {
@Override
public void makeSound(){
System.out.println("Kuhn!");
}
public void dogAttack(){
System.out.println("Biting");
}
}
Recommended Posts