2017年4月12日水曜日

[指導に使えたらいいなノート] 継承するとどうなるのかのJavaでのサンプル

extends(super, override)とabstractとconstructorが混ざったコードについて質問されたのでそこらへんについて指導用ノートの作っておこう.

extendsは日本語だと継承と呼ばれている.
既にあるクラスの中身を受け継いで新しいクラスを作ることができる.

継承があるおかげで一定部分は同じ実装で,それに加えて何か新しい機能を付け加えることができる.
(継承を使わないとコピペでやらないといけなくなり,もともとあったものと自分が実装したものがわかりずらくなることが多い.)
どんな人が設計しても登場する機能は基本的な機能として元となるクラスに実装して,オリジナル機能は継承先で実装するって状況で使われているのをよく見る気がする.

(1)継承先でも継承元のクラスに実装されたものが利用できる例

基本的に継承先と継承元のクラスの動作を確認するためにサンプルには,
A. mainを記述したコード
B. 継承元のクラスのコード
C. 継承先のクラスのコード
がそれぞれ含まれている.

mainを記述したコード
public class sampleMain{

    public static void main(String[] argv){
        sampleBetterCalculator sampleBetterCalc = new sampleBetterCalculator();
        sampleCalculator sampleCalc = new sampleCalculator();
       
        int result = sampleBetterCalc.add(1,4);
        int result2 = sampleCalc.add(1,4);
       
        System.out.println(result);
        System.out.println(result2);
    }
}

継承元のクラス(SampleCalculator)のコード

public class sampleCalculator{

    //aとbを足す
    public int add(int a, int b){
        return a+b;
    }
   
    //aからbを引く
    public int minus(int a, int b){
        return a-b;
    }
   
    //aとbを掛ける
    public int multiply(int a,int b){
        return a*b;
    }
   
    //aをbで割る
    public int devide(int a,int b){
        return a/b;
    }
   
}
 
継承先のクラス(SampleBetterCalculator)のコード
public class sampleBetterCalculator extends sampleCalculator{

    //3つの数の平均を計算する
    public int average3(int a,int b,int c){
        return (a+b+c)/3;
    }
   
    //角度を入れるとsinxが返る
    public double sinx(double x){
        return Math.sin(Math.toRadians(x));
    }
   
}

このコードを実行するとどちらのクラスのインスタンスもしっかりとaddメソッドを実行できていることがわかる.

図1: 例(1)のコンパイルと実行の結果
(2)継承先でオーバーライドしてみる
オーバーライドは継承先で継承元にあるメソッドを再定義(改変?)することである.

継承元のコードはそのままにmainがあるコードと継承先のコードを以下のように書き換える.

mainを記述したコード

 public class sampleMain{

    public static void main(String[] argv){
        sampleBetterCalculator sampleBetterCalc = new sampleBetterCalculator();
        sampleCalculator sampleCalc = new sampleCalculator();
        
        int result = sampleBetterCalc.minus(1,4);
        int result2 = sampleCalc.minus(1,4);
        
        System.out.println(result);
        System.out.println(result2);
    }
}

継承先のコード
public class sampleBetterCalculator extends sampleCalculator{

    //3つの数の平均を計算する
    public int average3(int a,int b,int c){
        return (a+b+c)/3;
    }
   
    //角度を入れるとsinxが返る
    public double sinx(double x){
        return Math.sin(Math.toRadians(x));
    }
   
    @Override
    public int minus(int a,int b){
        return b-a; //bからaを引くに変更
    }
   
}




図2: 例(2)を実行した結果


(3) 継承先で追加したものは(当然だが)継承元では呼び出せない
はそのうち追加



------
たまたま計算機能を継承して更に計算機能をリッチにしていく例をつくったので,これを利用してJavaFXを用いたGUI電卓のシリーズを書いてくれと言われたのでそのうちやるかもしれません...