多態性の基本
〈多態性〉
多態性を曖昧なイメージで説明すると
「あるものをあえてザックリ捉える」ことでさまざまなメリットを享受しようとする機能
キーワードは 「ザックリ」
厳密に言えばそれぞれ別の物体(車種)であるが、全部を「車」としてざっくり捉えた方が使いやすいこともある
→「車」と一括りにしてしまうことで、「車」と呼べば、具体的な車種は違ったとしても全て同じ物として扱える
ちなみに、カプセル化や継承と違って
多態性には専用の文法はない
→今まで使ってきた「代入の文法」でOK
〈多態性を使わない場合〉
public class Main{
public static void main(String args[ ]){
SuperHero h=new SuperHero( );
↑変数の型
(前提)
SuperHeroは、Heroを継承していて、HeroはCharacterを継承しているとする
Character
↑
Hero
↑
SuperHero
〈多態性を使ってザックリ扱いたい場合〉
public class Main{
public static void main(String args[ ]){
Character c=new SuperHero( );
インスタンス化の基本は
型=型
両方の型は同じ
ただし、ザックリと捉えたい時は違っていてもOK
Character c=new SuperHero( );
この場合、以後この変数を使いたい時は
本当はSuperHeroインスタンスでもザックリCharacterと捉えて利用する
⇩
あるインスタンスをどのように捉えるかは、どの箱に変数を入れるか(箱の型)で決まる
Character c=new SuperHero( );
↑ ↑
箱の型 中身そのものの型
箱の型.....そのインスタンスをザックリ「何として見なすか」様々な箱に入れることで扱い方を変えることが出来る
中身そのものの型....newされたら中身そのものの型はずっと変わらない
※ ただし、「代入が許される判断基準」はある
⇨ (キャラクターの箱の中にヒーローが入っている)
絵の内容が嘘ではないこと
↓
これをどのようにJVMは確認するのか?
そのためには、JVMに「~は~の一種である」という前提知識が必要
人間はわざわざ言わなくても前後の文脈で何となく理解できるが、
機械は前提としてきちんと宣言されてないと理解できない
↓
Javaでは、継承関係にあるクラスを「片方のクラスは他方のクラスの一種である(is-aの関係)」であると考える
すなわち、継承関係(親=子)でないと多態性は利用できない
多態性を使うためにも、絵に嘘がないように(箱の中にきちんと入るように)
継承関係を使うことが大事!
中身が被っているからといって、絵に嘘があるものを継承関係にするのはNG!
☆ インタフェースからはインスタンス化は出来ないが、子クラスを代入する箱として使用するのはOK(ザックリ捉えるために利用するのはOK)
ex. public interface Life{ //生き物インタフェース
public void run( );
}
public class Main{
public static void main(String args[ ]){
Life if=new Wizard( );
//ドラゴンインスタンスを生き物と書いてある箱に入れる
「今後Wizard( );はLifeとして捉えて使いますよ」という意味
※ちなみに捉え方は厳密である程、用途は増え、
曖昧である程、用途は減る
(曖昧)
紙 ・水分を含ませることが出来る
絵 ・水分を含ませることが出来る
・見て楽しめる
お金 ・水分を含ませることが出来る
・見て楽しめる
・物を買うことが出来る
(厳密)
例えば、全く同一である1つの存在(紙)に対して
複数の捉え方もすることが出来(紙なのか、絵なのか、お金なのか)
「それを何と捉えるかによって利用方法が変わる」
⇩
捉え方が曖昧で抽象的な程、用途は限定され
(紙-水を含ませることのみ)
具体的に捉える程、用途は増えていく
(お金-水を含ませる
見て楽しむ
物を買う)
この捉え方は後に出てくるJVMが呼び出せるメソッドの判断基準で必要
〈曖昧に捉えている程、呼び出せるメソッドは少なく
具体的に捉えている程、呼び出せるメソッドは多くなる〉