abstract、interfaceの使いどころについて学んだのでメモ兼アウトプット。
abstract
- abstractはメソッドとクラスに対して使用する。
- メソッド
- 実装の必要があるメソッドに対して、動作の詳細が決まってない場合、そのメソッドに対してabstractを指定する。
- abstractが指定されたメソッドを抽象メソッドという。
- クラス
- クラス内に抽象メソッドが一つでもあればそのクラスに対してabstractを指定する。
- abstractが指定されたメソッドを抽象クラスという。
- メソッド
※ ちなみにabstractとは、抽象、あいまい、という意味
Character.java
public abstract class Character {
public abstract void attack();
}
- abstractが指定されているクラスはインスタンス化(new)することができない。
Main.java
Character c = new Character();
// 以下のエラーが発生
// Main.java:3: エラー: Characterはabstractです。インスタンスを生成することはできません
- abstractクラスを継承する際、子クラスでabstractのメソッドをオーバーライドをしなければコンパイルエラーとなる(この特徴により親クラスに書かれているメソッドが子クラスに実装されることが担保される)。
interface
- abstractクラスの中でも、以下の条件を満たす場合はinterfaceクラスとして指定することができる(interface化するメリットについては後述)
- メソッドの全てにabstractが指定されている
- フィールド値がない
書き方は以下の通り、interface内のメソッドではpublic abstract
を省略することができる。(省略するのが慣例っぽい)
Creature.java
public interface Creature {
void run();
}
- interface化を行うメリットは、多重継承を行うことができる点。
- Javaでは多重継承(複数の親クラスから継承すること)が禁止されているが、親クラスがinterface化されていれば子クラスは複数の親を持つことが可能。
※ interface化された親を継承し、子クラス内で抽象メソッドを実装する際はクラス名の後にimplements
を付ける。それ以外の継承ではextends
。
PrincessHero.java
public class PrincessHero implements Princess, Hero {
// インターフェースの実装
public void run(){
System.out.println("スカートの裾をきつく結んで逃げ出した。");
}
}
Princess.java
// Princessインターフェース
public interface Princess {
void run();
}
Hero.java
// Heroインターフェース
public interface Hero {
void run();
}
- interfaceと前述のabstractを同時に継承することも可能。(以下の例では
Character
を継承)
PrincessHero.java
public class PrincessHero extends Character implements Princess, Hero {
// abstractの抽象メソッドを実装
public void attack() {
System.out.println("モンスターに攻撃。10のダメージ!");
}
// interfaceの抽象メソッドを実装
public void run() {
System.out.println("スカートの裾をきつく結んで逃げ出した。");
}
}