抽象メソッドとは、内容が空の関数の事です。
関数定義の先頭にキーワードabstractを付けます。
また、抽象メソッドを含むクラスは、抽象クラスになります。
抽象クラスは、クラス定義の先頭にキーワードabstractを付けます。
さらに、抽象クラスはインスタンス化できません。
内容が空の関数を作っても意味がないように思うかもしれませんが、
ちゃんと意味はあります。
抽象クラス・抽象メソッド
abstract class A {
abstract public void show();
}
class B extends A {
public int dataB;
public void show() {
System.out.printf("dataB = %d\n", dataB);
}
}
class C extends A {
public int dataC;
public void show() {
System.out.printf("dataC = %d\n", dataC);
}
}
public class Cmain {
public static void main(String[] args) {
B objA = new B();
C objA = new C();
objB.dataB = 10;
objB.show();
objC.dataC = 30;
objC.show();
}
}
このプログラムは、
クラスAに抽象メソッドであるshow関数があります。
抽象メソッドなので、関数の中身は空です。
このクラスだけでは、意味を持ちません。
次にクラスBとクラスCを見てみましょう。
それぞれAクラスを継承しています。
そして、Bクラス、Cクラス内でshow関数をオーバーライドして、
関数内容を記述しています。
ここで初めてshow関数が意味を持ちます。
続いてmain関数では、
単純にクラスBとクラスCのインスタンスを作成して、
メンバ変数に代入後、show関数を呼び出して値を表示しているだけです。
さて・・・クラスAに意味はあるでしょうか?
クラスAを定義しなくても、
それぞれ、クラスBとクラスCでshow関数を記述すれば良いような気がします。
しかし、クラスAを使うメリットもあります。
クラスAを定義する事によって、
クラスAを継承するクラスは、
メンバ変数の表示にshow関数を使うと決めておけば、
以後、クラスAを継承するクラスは、
メンバ変数の表示にshow関数を使う事を強制する事ができます。
抽象クラスを継承すると、
継承した派生クラス内で抽象メソッドをオーバーライドしない場合、
継承した派生クラス自体も抽象クラスとなってしまうからです。
Aクラスを継承しない場合、Bクラスのメンバ変数表示は、
display関数や、update関数のように、
どんな名前を付けるか分かりません。
これは、他人数でプログラミング作業を行う場合には、
一貫性がなくなります。
一方、クラスAの抽象メソッドを使えば、
クラスAを継承するクラスは、メンバ変数の表示にshow関数を使う。
と言う事が明確になり、プログラムを設計しやすくなります。
抽象メソッドが無い抽象クラス
抽象メソッドがなくても抽象クラスとする事もできます。
しかし、インスタンス化はできません。
abstractは付いていますが、抽象メソッドがないので、
このクラスは継承用として使って下さい。
と言うような意味になります。
abstract class A {
public void show() {
System.out.println("Hello");
}
}
class B extends A {
}
public class Cmain {
public static void main(String[] args) {
// A objA = new A(); // これはエラー
B objB = new B();
objB.show();
}
}