継承

継承とは、1つのクラスのデータと機能を継承する子クラスが未実装でデータと機能を所持することを意味します。
継承できるデータ及び機能は、public,proetecd,省略したフィールド、メソッドです。

継承を利用する事で次の事が実現可能となります。

  • クラスのグループ化。継承元の親クラスを継承した子クラスは、親クラスのグループに属するクラスとなります。
  • 共通化。継承元の親クラスのフィールド、メソッドはprivateを除き子クラスに全て継承され、利用できるようになります。
    即ち親クラスで定義したフィールド、メソッドは複数の子クラスに共通したフィールド、メソッドといえます。
  • 差分フィールド、メソッドの明確化。子クラスには、親のフィールド、メソッドにはないフィールド、メソッドを定義します。
    これにより、親クラスと子クラスの差分が明確に子クラスに表現されます。

その他諸々の継承の凄さと良さについては、実際のサンプルを動かして確かめましょう。

継承の構文

extends
public class 作成する子クラス exetends 継承元となる親クラス

継承のサンプル

初めてのJavaで説明したJavaの基本スタイルのサンプルクラス「HowToWriteJava」クラスを親クラスとします。

親クラスのHowToWriteJavaは、ダウンロードから取得して下さい。
※.ダウンロード後にprivateメソッドを全てprotectedに変更して下さい。

同じパッケージ階層に「ChildSample」クラスを作成します。

親クラス「HowToWriteJava」の変更箇所は、privateメンバーフィールド、privateメソッドをprotectedに変更しただけです。

上記イメージ図は、クラス設計に利用するUML図になります。

ChildSample Step1
/**
 * Copyright 2017 yourcompany.
 * 本ソースファイルの著作権は株式会社yourcompanyに所属します。
 * 株式会社yourcompanyの許可なくして、本ソースファイルの
 * 配布、改修、コピー、利用を禁止します。
 * 会社名               :株式会社yourcompany
 * 組織名               :システム開発部
 * プロジェクトコード   :education
 * バージョン           :1.0
 * 最終更新日時         :2017/02/10 17:21
 */
package jp.co.yourcompany.education.samples;

/**
 * このクラスは継承関係を理解するための子クラスです。
 * @author raita.kuwabara
 */
public class ChildSamples extends HowToWriteJava {

    /**
     * javaコマンドで起動されるmainメソッド
     * @param args javaコマンドで引き渡しされる引数
     */
    public static void main( String[] args ) {
        //sample1-1 デフォルトのメッセージ
        ChildSamples childSamples = new ChildSamples();
        childSamples.outputMessage();

        //sample1-2 outputErrorMessageが実行されるケース
        childSamples.init();
        childSamples.outputMessage();

        //sample2 引数を渡すケース
        //ChildSamples childSamples2 = new ChildSamples("子クラスの2つ目のインスタンスのHello");
        //childSamples2.outputMessage();

        //sample3
        HowToWriteJava.outputClassMessage();
    }
}
					
実行コマンドの手順
c:¥projects¥education>javac -d deploy¥classes -s src¥main¥java -encoding UTF8
	src¥main¥java¥jp¥co¥yourcompany¥education¥samples¥*.java 
c:¥projects¥education>jar -cvf deploy¥education-main.jar -C deploy¥classes .
c:¥projects¥education>java -cp deploy¥education-main.jar jp.co.yourcompany.education.samples.ChildSample
						
実行結果
こんにちは 日本へ
-------- END outputMessage method------------
メッセージが指定されていません。
-------- END outputMessage method------------
こんにちは 日本へ
						

親クラスのHotToWriteJavaクラスと同じ動きをしました。

ここで注目して頂きたいのが、HowToWriteJavaクラスのデフォルトコンストラクタでメンバーフィールドmessageに「こんにちは 日本へ」を
初期化処理としてHowToWriteJavaクラスに実装されています。これにより、outputMessageメソッドで「こんにちは 日本へ」が出力されています。

子クラスにデフォルトコンストラクタを実装していない場合には、
インスタンスを生成時に親クラスのデフォルトコンストラクタが実行されます。

継承におけるデフォルトコンストラクタ

次にChildSampleクラスのmainメソッドで//sample2 引数を渡すケース以下の2行がコメントになっています。
このコメントを外して、コンパイルしてみて下さい。
「コンストラクター ChildSamples(String) は未定義です。」とエラーメッセージが出力されました。

親クラスの引数有りのデフォルトコンストラクタは、子クラスに継承されません。

親クラスの引数有りのデフォルトコンストラクタをそのまま利用したい場合には、次のようにします。

ChildSample Step2
//コメント割愛
package jp.co.yourcompany.education.samples;
//コメント割愛
public class ChildSamples extends HowToWriteJava {

    /**
     * 指定したメッセージを出力する。
     * @param message メッセージ
     */
    public ChildSamples( String message ){
        super( message );
    }
    //main メソッド割愛
}
					

親の引数有りデフォルトコンストラクタをsuper( String型 )を指定することで、
親クラスの引数有りのデフォルトコンストラクタpublic HowToWriteJava( String message ) { //省略 } が実行されます。

super()で親の引数なしデフォルトコンストラクタの実行を意味します。
super( 引数 )は、親の引数ありコンストラクタのうち、引数の数と引数のそれぞれの型と一致したコンストラクタを実行します。

上記ソースファイルをコンパイルして下さい。Step1で実行できた new ChildSamplesでエラー「コンストラクター ChildSamples() は未定義です」が発生しました。

子クラスに1つでもデフォルトコンストラクタを実装した場合には、
未実装で利用していた親クラスのデフォルトコンストラクタは利用できなくなり、明示する必要があります。
ChildSample Step3
//コメント割愛
package jp.co.yourcompany.education.samples;
//コメント割愛
public class ChildSamples extends HowToWriteJava {

    /**
     * デフォルトコンストラクタ
     */
    public ChildSamples(){
        super();
    }
    /**
     * デフォルトコンストラクタ
     * 指定したメッセージを出力する。
     * @param message メッセージ
     */
    public ChildSamples( String message ){
        super( message );
    }
    //mainメソッド割愛
}
					

子クラスのデフォルトコンストラクタでspuer()を指定することで親のデフォルトコンストラクタを実行します。

super,this

super構文
super():親クラスのデフォルトコンストラクタを実行します。
super( 引数1, 引数N ):親クラスのコンストラクタのうち、指定した引数の数とそれぞれの型に一致したコンストラクタを実行します。
spuer.フィールド:親クラスメンバーフィールドを指定します。
spuer.メソッド名( ):親クラスの指定したメソッドを実行します。
spuer.メソッド名( 引数1 , 引数N):親クラスの指定したメソッドのうち、引数の数とそれぞれの型に一致したメソッドを実行します。

superは親クラスを意味しますが、thisは作成した子クラス自身を意味します。

this構文
this():自クラスのデフォルトコンストラクタを実行します。
this( 引数1, 引数N ):自クラスのコンストラクタのうち、指定した引数の数とそれぞれの型に一致したコンストラクタを実行します。
this.フィールド:自クラスメンバーフィールドを指定します。
this.メソッド名( ):自クラスの指定したメソッドを実行します。
this.メソッド名( 引数1 , 引数N):自クラスの指定したメソッドのうち、引数の数とそれぞれの型に一致したメソッドを実行します。

ChildSample.javaのダウンロードと実行方法

java_sample9.zipファイルを「c:¥download¥java¥samples¥」に保存して下さい。

java_sample9.zipファイルを「c:¥projects」配下に展開して下さい。

コマンドプロンプトを起動して、「sample9.bat」を実行して下さい。

javac,jar,javaコマンドが随時実行されて、子クラスのmainメソッドが実行されます。

Linux,Unix,iOSの方はバッチファイルはお手数ですが作成して下さい。改行コードが「CRLF」の点ご留意ください。