多態性 変数の型の判断と動作
ザックリ捉えた変数の箱にインスタンスを代入した時点で、
JVMはその変数としか中身を判断できなくなってしまう
ex. public class Main{
public static void main(String args[ ]){
Wizard w=new Wizard( );
Character c=w; //Characterの箱にWizardを代入
この時点でJVMはwをCharacterとしてしか判断できなくなる
(箱に入った時点でJVMは箱の中身がWizardであったことを忘れてしまう)
〈曖昧な型の箱へのインスタンスの代入〉
インスタンスを曖昧に捉えることになり、
「厳密には何型のインスタンスだったか」がJVMには分からなくなってしまう
ただ確実に言えることは、「この箱に入っているのはCharacterの一種」ということだけ。
⇩
そうなると、メソッドを呼び出すときにCharacterクラスに定義されているものだと呼び出す事ができるが、
Wizardクラスに定義されているものだと呼び出すことが出来なくなる
ex. c.attack(m);
//Characterクラスにあるメソッドなので、実行される
c.fireball(m);
//Wizardクラスにはあるが、Characterクラスにはないメソッドなので、実行できない
なぜか?
JVMはCharacter型クラスに入っていることしか分からなくなってしまったから
(JVMからすると、この時点ではもしかしたら中身はCharacterクラスを継承しているHeroクラスが入っている可能性も考えるため、Wizardクラスにあるメソッドを安易に実行できない)
⇩
Wizardクラスを「Character」とざっくり捉えている限り(=Character型の変数の箱に入れている限り)、
私達は少なくとも「Characterなら出来る最低限の事」しか命令できない
=Characterとして持つメソッドだけしか外部から呼び出すことが出来ない
(前提として入れた箱にある方あるメソッドを呼んでいる)
もしメソッドが呼べたら、その動きはどうなるか?
インスタンスの中身に書いてある具体的な記述の内容の動作が実行される
なぜなら、Characterクラス(抽象的な方)のメソッドの中身は、抽象的であるが故にabstractメソッド(詳細未定メソッド)の可能性もあるので、
具体的なクラスの確実に書いてある方を呼ぶ方が安全
ex.public abstract class Monster{
public void run( ){
System.out.println("逃げ出した");
} → メソッドA
}
public Slime extends Monster{ //Monsterクラスを継承してSlimeクラスを作る
public void run( ){
System.out.println("撤退した");
//run( )の中身をオーバーライド(上書き)
} → メソッドB
}
public class Main{
public static void main(String args[ ]){
Monster m=new Slime( ); //SlimeをMonsterとしてザックリ捉える
m.run( );
//メソッドBの方が実行される(Monster型の中身の方に入っているSlimeクラスの中身)
☆ まとめ
[箱の型] どのメソッドを「呼べるか」を決定する
[中身の型] メソッドが呼ばれたら、「どう動くか」を決定する