前回
B b = (B)aの挙動を見てみよう(インスタンスメソッド版)
Java(A.java)
public class A{
public void speak() {
System.out.println("Hello");
}
}
Java(B.java)
public class B extends A{
public void speak() {
System.out.println("Good Morning");
}
}
復習だが、BはAを継承し、speakメソッドをオーバーライドしている。この時、Mainクラスで以下の処理を実施する。
Java(Main.java)
public class Main {
public static void main(String[] args) {
A a = new B();//復習
a.speak();//復習
B b = (B)a;
b.speak();
}
}
問題はA型の変数aをキャスト演算子で明示的にB型とし、B型の変数bに格納していることである。
キャスト演算子をつけない場合
以下のコンパイルエラーが発生するので、ダウンキャストの場合は必ずつける
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
型の不一致: A から B には変換できません
at Main.main(Main.java:5)
さて結果はどうなるだろうか。
Good Morning
Good Morning
変数bはB型なので、Bクラスのspeakが呼び出された。
B b = (B)aの挙動を見てみよう(staticメソッド版)
ではspeakメソッドにstaticをつけて確認しよう。
Java(A.java)
public class A{
public static void speak() {
System.out.println("Hello");
}
}
Java(B.java)
public class B extends A{
public static void speak() {
System.out.println("Good Morning");
}
}
Java(Main.java)
public class Main {
public static void main(String[] args) {
A a = new B();//復習
a.speak();//復習
B b = (B)a;
b.speak();
}
}
結果
Hello
Good Morning
この場合もBクラスのspeakが呼び出されることに注意。インスタンスメソッドと同様に元の型であるB型にキャストで戻し、B型で宣言した変数に代入しているため、呼び出すメソッドもBクラスのものになる。
Bクラスだけに存在するメソッドを呼び出す時は?(staticメソッド版)
今度は以下のようにBクラスにのみbyeメソッドを追加する。
Java(B.java)
public class B extends A{
public static void speak() {
System.out.println("Good Morning");
}
public static void bye() {
System.out.println("bye");
}
}
それをMainクラスで呼び出そう。
Java(Main.java)
public class Main {
public static void main(String[] args) {
A a = new B();
a.bye();
B b = (B)a;
b.bye();
}
}
結果
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
メソッド bye() は型 A で未定義です
at Main.main(Main.java:4)
上記のようにエラーになることは想像しやすいだろう。一旦エラー部分をコメントアウトして再確認する。
Java(Main.java)
public class Main {
public static void main(String[] args) {
A a = new B();
// a.bye();
B b = (B)a;
b.bye();
}
}
結果
bye
b.bye()の結果はエラーにならなかった。このことからもbはB型で定義できていることがよくわかる。
まとめ
- インスタンスメソッドの場合、実際のオブジェクト(new B())に基づいて、サブクラスのメソッドが優先的に呼び出される
- staticメソッドの場合、変数の型(A)に基づいてメソッドが決定される