whichのブログ ~プログラミング体験記~ -21ページ目

whichのブログ ~プログラミング体験記~

主にJava,vVsual C#,Andoroid,SQLについて
覚え基本た文法やプログラミング技法、各クラスの利用法を
忘れないように形にしたものです

初心者だとかプロだとか特に意識せず利用してもらえるとうれしいです。

タイトルどおり今回は前回やった継承を利用することで実現できるメソッドの振る舞いです

■オーバーライドの基本的用法

「オーバーライド」は「オーバーロード」のように同じメソッド名を使います
オーバーライド=再定義の言葉通り継承した親クラスにあるメソッドの処理内容をまったく別のものに書き換えたり処理の前後に処理を追加したりするときに利用する

■サンプルプログラム
今回取り扱うヤツはソースコードを見ないとピンと来ないはずなので、
public class SuperProg {
 String name;
 public SuperProg(String name) {this.name = name; }
 public void show() {System.out.println("親は" + name) ; }
}

public  class SubProg extends SuperProg {
      public SubProg(String name) {super(name);}
      public void show() { System.out.println("オーバーライドしたので新しい親は" + name) ; }
}

public class SubProg2 extends SuperProg{
      public SubProg2(name) { super(name) ; }
     public void show(String name) { 
            super.show();
            System.out.println("オーバーライドしたけど親の処理は完了した!") ;
            System.out.println("それを実現した子は" +name2); 
    }
}
public class MainProg{
          public static void main(String [] age) {
                    SuperProg  sp   = new SuperProg("田中");
                    SubProg     sb  = new SubProg("鈴木");
                    SubProg2   sb2  = new SubProg2("田中");
                    
                    sp.show();      //1
                    sb.show();      //2
                    sb2.show("伊藤");    //3
          }
}

--------------
 †実行結果†
--------------
親は田中
オーバーライドしたので新しい親は鈴木
親は田中
オーバーライドしたけど親の処理は完了した!
それ実現した子は伊藤
---------------
それぞれのクラスの出力を注釈で1,2,3と区別してみました
1はスーパークラスのメソッドで実行結果の1行目です
2はサブクラスでオーバーライドしているので同じメソッドを呼び出しても中身が違うのでまったく違う処理なので実行結果の2行目です
3はオーバーライドをするけどもスーパークラスの処理は残しておきたいというメソッドで実行結果ではまずスーパークラスの処理をするため3行目が1行目と同じになる。そして4行目と5行目はオーバーライドしたサブクラスの処理です

こんなかんじでメソッドを1からカスタマイズしたり拡張させる感じで追加カスタマイズをスーパークラスにするのがオーバーライドです
注意する点はオーバーライドするメソッドはfinal修飾子がないことぐらいです。

■オブジェクト変数の暗黙的型変換
 double ten;
   ten = 1.5;
   ten+= 10;
   ten*=2;
  System.out.println(ten);
のように数値型の場合int数値を「double」や「long」に入れてもなにエラーにならず上記の実行結果で「ten」は「23.0」と出力される
int →long→double→Stringといった感じで変数の大きさが決まっており右へ行くほど大きいため矢印の向きを間違えなければ型変換の記述をしなくても動作してくれる(向きを間違えると必ずコンパイルエラー)

継承関係が成立するクラスの間でも似たようなことができる

Classスーパークラスのコンストラクタサブクラスのコンストラクター
スーパークラス
サブクラス×


考えてみれば当然のこですね

■ポリモリフィズム
上記の表からスーパークラスはサブクラスのコンストラクターを使っても生成可能

ポリモリフィズムはいろいろなところで
     「同じ呼び出しで異なる振る舞いをする」
と説明されてるがこれをJava風に言い直すと
「スーパークラスをサブクラスのコンストラクタで生成し、サブクラスがオーバーライドしたメソッドを実行する」
この場合サブクラスは複数存在している
あまり言葉じゃ説明できなさそうなので、オーバーライドのときに使った3つクラスを使って解説します

public class MainCall{
        public static void main(String [] age) {
              SuperProg  sp1 = new SubProg("山田");  //SubProgのふるまい
             SuperProg  sp2 = new SubProg2("渡辺");  //SubProg2のふるまい  
             
             System.out.println(1);
             sp1.show();
             System.out.printlen(2);
             sp2.show("伊藤");
   }
}
--------------
 †実行結果†
--------------
1
オーバーライドしたので新しい親は山田

親は渡辺
オーバーライドしたけど親の処理は完了した!
それ実現した子は伊藤
---------------
つまりshow()の出力がどちらも同じSuperProgのオブジェクトなのにサブクラスとして振舞っていることになる
これでどちらもSuperクラスのshow()メソッドを呼び出しているが振る舞いがことなる状況となった
これこそポリモルフィズムである
しかしこれができるのはあくまでオーバーライドしたメソッドのみであって継承後に追加したメソッドを呼び出すとエラーになる