多態性 入れたインスタンスと同じ型に再び戻したい時 〜instance of〜
〈ザックリとした型に代入した後、入れたインスタンスと同じ型に再び戻したい時〉
Character c=new Wizard;
↑WizardをCharacterと見なす
これによってcに対してCharacterクラスにはない(Wizardクラスにしかない)メソッドのfireball( );は呼べなくなる
(Javaからはcの中身が厳密にWizardなのかどうか判断できなくなったので)
⇩
fireball( );をどうしても使いたい時は変数cの中身を「Wizardであると捉え直す」
必要がある
!単純に入れ直してみる
Character c=new Wizard; //Wizardをcに代入してから
Wizard w=c; //cをWizard型に代入し直してみる
→エラー
理由:そもそもJVMによる解釈は前後の文脈関係なく1行ずつしている
1行目のCharacter型に代入した時点で、JVMは変数cをCharacterクラスを継承しているHeroかもしれないし、Wizardかもしれないし、Thiefかもしれないと捉えている
2行目の時点では「cはCharacterクラスを継承している何か(Hero/Wizard/Thief)」とJVMは捉えているので、Wizard型とは確実には判断できない状態
なので、Wizard型には代入できない
(もし変数cの中身がHeroだったのにWizard型に代入してしまったら危険)
⇩
それでも強制的にWizard型と見なしてほしい時
キャスト演算子を使う
キャスト演算子とは....
強制的な型変換をコンパイラに対して指示するとても強力な演算子
Wizard w=(Wizard) c;
このように「曖昧な型に入っている中身を厳密な型に代入する」キャストを特に
ダウンキャスト(down Cast)という
(失敗の危険が伴うから)
⇩
この危険性を少しでも回避するために、
「キャストしても大丈夫か?」を事前にチェックする必要がある
そのために使う演算子
変数 instance of 演算子
変数 instance of 型名
この演算子を使うと、変数の型名の箱に代入可能であれば、trueが返ってくる
!これでチェックすれば、危険回避が可能
〈instance of 演算子〉は
「指定の型に代入して、絵として嘘にならないか」を判定してくれる
ex. Wizard型に入れ直す
中身 Wizard → Wizard OK!
〈Character型〉 〈Wizard型〉
中身はWizardだが、 Hero型に入れ直す 絵として嘘になるので
Wizard → Wizard NG
〈Character型〉 〈Hero型〉
ex.
if (c instance of SuperHero){ //もしcの中身をSuperHeroと見なして大丈夫なら
SuperHero h=(SuperHero) c; //強制的にSuperHero型に入れる
h.fly( ); //SuperHeroにだけあるメソッドを実行してみる
} →OK!
(通常ダウンキャストしていない場合であれば、CharacterクラスにはなくてSuperHeroクラスにはあるメソッドは呼び出すことが出来ない)