定義
- インスタンス化できないクラス
- 継承させることを前提として作るクラス
- 一種の仕様である
以下のようにclassの前にabstractを付加することで抽象クラスとなる
public abstract class クラス名 {
...
}
抽象メソッド
抽象メソッドとは処理の本体がないメソッドのこと。つまりはオーバーライドさせることが前提となっている。
以下のようにメソッドの宣言でabstractを加えるとそのメソッドは抽象メソッドとして扱われ、コードブロックはなく ; を記述する。
public class Character {
// 省略
public abstract void attack(Matango m);
}
ちなみにこのコードをコンパイルすると以下のようにエラーが発生する。
.\Character.java:1: エラー: Characterはabstractでなく、Character内のabstractメソッドattack(Matango)をオーバーライドしません
public class Character {
^
エラー1個
このエラーの原因はクラスCharacterが抽象メソッドを持つことから抽象クラスとなるため、以下のように必ずクラスの宣言でもabstractを付加する必要がある。
public abstract class Character {
// 省略
public abstract void attack(Matango m);
}
抽象クラスは継承しても抽象メソッドをオーバーライドしなければコンパイルエラーとなる。
ここで一例として先ほど定義した抽象クラスのCharacterを継承したコード例を示す。
public class Dancer extends Character {
public void dance() {
System.out.println(this.name + "は情熱的に踊った");
}
}
このコードは新たにDancerクラスを作るコード例であるが、先ほど挙げたように継承したCharacterクラス内の抽象メソッドattackをオーバーライドしていないため、以下のコンパイルエラーを発生させる。
.\Dancer.java:1: エラー: Dancerはabstractでなく、Character内のabstractメソッドattack(Matango)をオーバーライドしません
public class Dancer extends Character {
^
エラー1個
そのため、以下のように抽象メソッドattackをオーバーライドしてDancerクラスを作ることでコンパイルが可能となる。
public class Dancer extends Character {
public void dance() {
System.out.println(this.name + "は情熱的に踊った");
}
public void attack(Matango m) {
System.out.println(this.name + "の攻撃");
System.out.println("敵に3ポイントのダメージ");
m.hp -= 3;
}
}
抽象クラスを継承しインスタンス化するクラスを具象クラスという。
ほか気づいたこと
- 抽象メソッドを持つならば抽象クラスである必要はあるが、逆は成立しない(抽象クラスだからといって、メソッドを持つ必要があるわけではないし、具象メソッドを持っていてもjava的には問題ない)
- 抽象クラスとして宣言するとき、極論フィールド、メソッドどちらも持たずに空でも宣言はできる
- 抽象クラスのインスタンス化はできないが、コンストラクタは定義可能。(ただ、前回でココンストラクタが定義されていない場合、自動的にデフォルトコンストラクタが作成されることを考えるとやはり作成した方がよいと思われる)
- 抽象クラスは抽象クラスとして継承もできる(多段継承)
多段継承では末子クラスでの実装義務が重くなったり、上位クラス変更の影響が大きいため、別で説明するインターフェイスで代用できないかなどを考える必要があるとのこと。