抽象クラス

抽象クラスはabstract宣言されたクラスであり、抽象メソッドを含んでも含まなくてもよいです。
抽象クラスはインスタンス化することはできませんが、サブクラス化することはできます。
抽象メソッドは、実装なしで宣言されたメソッドです

抽象クラスの概念としては、インターフェイスと実体クラスの間の位置づけのクラスとして理解しておけば良いでしょう。

抽象クラスの特徴は以下になります。

  1. 公開するメソッドの強制的な実装
    抽象クラスに宣言された抽象メソッド(abstract method)は、継承した子クラスまたはその子クラスで実装を強制します。
    継承先で親クラスで宣言された抽象メソッドが抽象メソッドのままの場合には、子クラスもabstractクラスである必要があります。
  2. 子クラス群への実装差異の明確化
    抽象クラスを継承した子クラス群は、それぞれ抽象クラスを実装しますが、それぞれの子クラスの動作を実装します。

抽象クラスは、Javaの慣習で接頭語に「Abstract」を付与します。

abstract 構文

abstract class
public abstract class AbstractHoge {}
abstract メソッド
protected abstract 戻り型 メソッド名( 引数型1 引数名1 , 引数型N 引数名2 );

抽象クラスのサンプル

上記UMLのように、AbstractSampleクラスのexecAllSamples()メソッドが抽象メソッドになっています。
AbstractSampleクラスは継承した子クラスがexecAllSamples()メソッドを実装しています。

AbstractSamples.java
//ライセンスコメント割愛
//package宣言部
package jp.co.yourcompany.education.samples;

/**
 * 抽象クラスサンプル
 * @author Raita.Kuwabara
 */
public abstract class AbstractSamples {

    /**
     * 継承した子クラスのサンプルを全て実行する
     */
    protected abstract void execAllSamples();

    /**
     * メソッド共通の開始文の定型出力
     * @param methodName 出力するメソッド名
     */
    protected void outputStartMethod( String methodName ) {
        System.out.println("----- " + methodName + " START -----");
    }

    /**
     * メソッド共通の開始文の定型出力
     * @param methodName 出力するメソッド名
     */
    protected void outputEndMethod( String methodName ) {
        System.out.println("----- " + methodName + " END -----");
    }
}
		
SimpleSample.java
//ライセンスコメント割愛
package jp.co.yourcompany.education.samples;

/**
 * 抽象クラスを継承した子クラスのサンプル
 * @author Raita.Kuwabara
 */
public class SimpleSample extends AbstractSamples {

    /**
     * サンプルを全て実行する。
     */
    @Override
    public final void execAllSamples() {
        outputStartMethod( "execAllSamples" );
        outputMessage();
        outputStartMethod( "execAllSamples" );
    }

    /**
     * メッセージを標準出力に出力する。
     */
    private void outputMessage(){
        System.out.println("SimpleSample.execAllSamples ");
    }

    public static void main(String[] args){
        SimpleSample samples = new SimpleSample();
        samples.execAllSamples();

        //抽象クラスなのでインタタンスは生成できません。
        //以下のコードはNG
        //AbstractSamples abstractSamples = new AbstractSamples();
        //abstractSamples.execAllSamples();
    }
}
				

サンプルのダウンロードと実行方法

  • java_sample11.zipファイルを「c:¥download¥java¥samples¥」に保存して下さい。
  • java_sample11.zipファイルを「c:¥projects」配下に展開して下さい。
  • コマンドプロンプトを起動して、「sample11.bat」を実行して下さい。
  • javac,jar,javaが実行されてSimpleSamplesが実行されます。
  • Linux,Unix,iOSの方はバッチファイルはお手数ですが作成して下さい。改行コードが「CRLF」の点ご留意ください。

一流のサンプル

インターフェイスや抽象クラスをクラス設計から起こし、実装で利用できるには最低3年以上かかります。

このようなケースは一流のソースを見て感じた方が理解が早いです。
一番上位に位置づけられているのがErorrsインターフェイスです。
3つの実態クラス(MapBindingResult,BeanPropertyBindingResult,DirectFieldBindingResult)があります。
インターフェイスで必ず実装しなくてはならないメソッドを明示したうえで、各オブジェクトで実態化されていきます。
インターフェイスの全てのメソッドを実装していないので、abstractクラスとして定義されます。

ソースファイルの見方は、詳細を捉える必要はありません。
メソッド名の完全一致(戻り値、メソッド名、引数)したメソッドを親と子クラスで見比べていきます。

一流のスタンスを学ぶために用意したので、今は分からなくても凡その
インターフェイス、抽象クラス、クラスの繋がりが感じられれば幸いです。

以下にSpringFrameworkのspring-contextパッケージ内のvalidationを抜粋したzip(15Kb程度)をダウンロードできるようにしています。

©Pivotal Software

final修飾子

本頁のサンプル及び一流のソースコードにfinal修飾子が幾つか見受けられました。

final修飾子は親クラス、インターフェイスで定義した抽象メソッドやprotectedメソッドのオーバライド(実装)が 子クラス内で最後であることを意味します。

final修飾子が付与されたメソッドは、子クラスでオーバライドができません。

final class
public final class HogeClass exetends 親クラス {}
final method
@Override
public final 戻り値 メソッド名( 引数 ) {}