abstract を利用する時には以下のような事がらを知っておく必要があります。
abstract はクラス・メソッド宣言時に付与し、クラス・メソッドを抽象クラス(abstract クラス)・抽象メソッド(abstract メソッド)として宣言します。以下は、抽象クラスの定義の記述形式です。
abstract class クラス名 {
}
以下は抽象メソッドの定義の記述形式です。
abstract 戻り型 メソッド名(引数型 引数名);
抽象メソッドは実装を持たないため、「{}(処理)」は必要ありません。
抽象クラス・メソッドはオブジェクト生成出来ないので、一見使い道が無いように思えます。抽象クラスはサブクラスで継承され、そのサブクラス内で抽象クラスで実装されていない抽象メソッドをオーバーライドし処理を実装して、抽象クラスに、抽象メソッドと具象メソッドの両方を記述することができます。
以下が抽象クラス利用したプログラムの例です。
abstract class AbstractTest {
protected String messeage;
public void abstractMain(String m) {
//具象メソッドの作成
messeage = m;
System.out.println(messeage);
}
//抽象メソッドの作成
abstract void abTest();
}
以下は上記の「AbstractTest」クラスを継承したクラスその一です。
public class ExTest1 extends AbstractTest {
private String exTest1M;
public ExTest1(String m) {
exTest1M = m;
System.out.println(exTest1M);
}
public void abTest() {
System.out.println("ExTest1クラスです。");
System.out.println(exTest1M);
System.out.println(messeage);
}
}
以下は上記の「AbstractTest」クラスを継承したクラスその二です。
public class ExTest2 extends AbstractTest {
private String exTest2M;
public ExTest2(String m) {
exTest2M = m;
System.out.println(exTest2M);
}
public void abTest() {
System.out.println("ExTest2クラスです。");
System.out.println(exTest2M);
System.out.println(messeage);
}
}
そして、以下が上記のクラスたちを呼び出すメインクラスになります。
public class MainTest {
public static void main(String[] args) {
//抽象クラスの配列の作成
AbstractTest at[] = new AbstractTest[2];
//ExTest1クラスのオブジェクトを0番目に格納
at[0] = new ExTest1("ExTest1をnewしました。");
at[0].abstractMain("配列0番目です。");
//ExTest2クラスのオブジェクトを1番目に格納
at[1] = new ExTest2("ExTest2をnewしました。");
at[1].abstractMain("配列1番目です。");
//abTestメソッドの呼び出し
for (int i = 0; i < at.length; i++) {
AbstractTest ab = at[i];
ab.abTest();
}
}
}
以下が実行結果です。
ExTest1をnewしました。 配列0番目です。 ExTest2をnewしました。 配列1番目です。 ExTest1クラスです。 ExTest1をnewしました。 配列0番目です。 ExTest2クラスです。 ExTest2をnewしました。 配列1番目です。上記のプログラムの例では、抽象クラスから二つのサブクラスを拡張しています。抽象クラスではオブジェクトの作成することは出来ませんが、 二つのサブクラス内でオブジェクトを作成できるようにしています。
メソッドの定義のみ宣言し、実装を継承したサブクラスに任せるといったことを考えると抽象クラスとインタフェースは似ている役割をはたしていることになります。
しかし、抽象クラスとインターフェイスには以下のような違いがあげられます。