こんにちは。
ときです。>∩(・ω・)∩<
皆さんは、なかなか覚えられない言葉ってありますか?
スマホの「ホームボタン」を「ハウスボタン」と覚えてしまったり、
「シミュレーション」のことを「シュミレーション」と覚えてしまったり、
アルファベットの「S」と言われたのに「C」を書いてしまったり……
僕は「ポリモーフィズム」がどうしても覚えられません。頭の中でどうしても「ポリフォーリズム」に変換されてしまいます。このブログを書いているときもさっそく「ポリフォーリズム」と書いてしまいました……
さて今日は、僕がどうしても覚えられない「ポリモーフィズム」のお話です。
多態性(ポリモーフィズム)
・親クラスの型で子クラスをインスタンス化できる(アップキャスト)
・アップキャストすると、親クラスにあるメソッド、フィールドは使える
・アップキャストでは子クラス独自のメソッドフィールドは使えない
という仕組みのことだそうです。挙動については、下のコードを参考にしてみてください。コードの解説は下に書きます。
public class Polymorphism { public static void main(String[] args) { <span style="color: #3366ff;">Human human = new Human();</span> human.print(); <span style="color: #ff0000;">Human sister = new Sister();</span> sister.print(); //コンパイルエラーになる↓ //sister.print("花沢"); <span style="color: #00ff00;">Sister sis =(Sister)sister;</span> sis.print("花沢"); } } class Human{ String name = "人間"; void print(){ System.out.println("わたしは"+name); } } class Sister extends Human{ String name = "花子"; @Override void print(){ System.out.println("私は"+name); } void print(String sisterName){ System.out.println("私は"+sisterName); } }
上の青く塗ったコードのところが通常のインスタンス化です。
Human型で作成したhuman変数を使うと、Humanクラスのフィールドとメソッドを呼べます。なので、human.print();の結果は「わたしは人間」となります。
さて、問題は他のインスタンスです。
赤く塗ったコードに注目してください。ここでは、Human型で作成したsister変数が、アップキャストされています。
このsister変数を使うことでも、Humanクラスのフィールド、Humanクラスのメソッドを呼び出すことができるようになります。あれ?最初のインスタンスと変わらないじゃん?と思うかもしれませんが、SisterクラスがHumanクラスと共通の部分を持っていた場合は、Sisterクラスのメソッド・フィールドを呼び出すことができます。
sister.print();を実行すると「私は花子」とコンソールに表示されます。
printメソッドがHumanクラスにもあるので共通部分だと判断され、Sisterクラスのprintメソッドが呼び出されます。
ただし、printメソッドでも引数1個設定したものは、Sisterクラス独自のものなので、アップキャストしたsister変数では呼び出すことができません。
こういった場合は、緑色に塗った形でダウンキャストしてあげるか、きちんとSister型変数でインスタンス化をしてあげる必要があるようです。
親クラスの型で子クラスをインスタンスする機会があれば使えるのかな、と思いました。抽象クラスにメソッドを用意して、抽象クラスの型で子クラスをインスタンス化すれば、そこそこ扱う機会もあるのかも…という印象です。
子クラスをまとめて、一斉に同じメソッド名を呼び出したいときなんかには使えそうなので、挙動をしっかり覚えていきたいです。
テストでミスが多かった部分なので、今回は少しだけ真面目に書いたつもりです。「何を言っているのかよくわからないよ!もうちょっとかみ砕いて説明してよ!」というお声がありましたら、そっと教えてください。もう少しだけかみ砕いた説明ができるように頑張ってみます。それでは!