抽象クラスとは
抽象クラスは、そのクラス自身のオブジェクトを生成することはできません。通常抽象クラスは実装のないいくつかの抽象メソッドを持っており、サブクラスで抽象クラスを継承し、そのサブクラス内で抽象クラスで実装されていない抽象メソッドを実装(オーバーライド)しオブジェクトを生成する形をとります。
例えば[ 社会人 ]クラスと、それを継承する[ システムエンジニア ]、[ バスの運転手 ]クラスを考えてみましょう。
「出社する」とか、「休暇を取る」といった共通的な機能は基底クラスである[ 社会人 ]で実装出来るかもしれませんね。では[ 社会人 ]として必要不可欠な「仕事をする」という機能を実装したいとします。
しかし[ システムエンジニア ][ バスの運転手 ]では仕事の内容が異なるので[ 社会人 ]では実装できません。このような時、 抽象メソッドとして[ 社会人 ]クラスで「仕事をする」を定義し、各サブクラスで実際の「仕事をする」を実装します。
抽象クラスには以下のようなルールがあります。
- 抽象クラスのオブジェクトを生成することはできません。
- 抽象メソッドがあるクラスは必ず抽象クラスとして宣言しなければいけません。
- 抽象メソッドがない、抽象クラスを宣言することもできます。必ず継承が行われ、なんらかのメソッドの変更があることを表します。
- 抽象クラスを継承したサブクラスで抽象メソッドを実装(オーバーライド)しない場合、そのサブクラスは抽象クラスとして宣言されます。
抽象クラスの定義
先ず抽象クラスを定義するには、クラス修飾子「 abstract 」を使用します。
abstract class WorkingPeople {
// 休暇を定義
public void vacation{
System.out.println("休暇を取ります。");
}
}
上記の[WorkingPeople]クラスは抽象クラスとして宣言していますので、このクラス自体をインスタンス化することは出来ません。また、このクラスには抽象メソッドはありませんが、抽象クラスとして宣言することは可能です。
次に抽象メソッドの定義です。メソッドの定義もクラス同様、修飾子「 abstract 」を使用します。
abstract class WorkingPeople {
// 休暇を定義
void vacation(){
System.out.println("休暇を取ります。");
}
// 働くを抽象メソッドとして定義
abstract void work();
}
抽象メソッドとして「work」を定義しました。抽象クラスとして宣言したメソッドには操作を定義することは出来ません。また、抽象メソッドはサブクラスでオーバーライドしますので、サブクラスから参照できない「 private」や、オーバーライドを許可しない「 final」修飾子は矛盾するため付けることが出来ません。
抽象クラス・メソッドを使った際の矛盾した修飾子は SJC-Pで良く出題されますので覚えておきましょう。
抽象クラスの利用
社会人クラスを継承した[システムエンジニア]、[バスの運転手]を作成してそれを利用してみます。
Example_09.java
abstract class WorkingPeople {
// 休暇を定義
void vacation(){
System.out.println("休暇を取ります。");
}
// 働くを抽象メソッドとして定義
abstract void work();
}
class SE extends WorkingPeople {
// 抽象メソッドを実装します
void work(){
System.out.println("システム設計します");
}
}
class Driver extends WorkingPeople {
// 抽象メソッドを実装します
void work(){
System.out.println("運転します");
}
}
public class Example_09{
public static void main(String[] args){
WorkingPeople wpA = new SE();
WorkingPeople wpB = new Driver();
wpA.work();
wpB.work();
}
}
システム設計します
運転します
このように基底クラスにて抽象メソッドを宣言した場合、サブクラスでは抽象メソッドを実装することが必要になるので、サブクラスで実装するべき振る舞いの実装を強制することが出来ます。
|