定義
抽象クラスでの定義でも挙げた3つを同様に持つ(改めて下記に提示)
- インスタンス化できないクラス
- 継承させることを前提として作るクラス
- 一種の仕様である
それに加えて - 全てのメソッドは抽象メソッドであること(調べてみると、java8からは具象メソッドも取ることができるようである)
- 基本的にフィールドを1つも持たない
これらの条件を満たす特に抽象度の高いクラスをインターフェイスとして特別に扱うとのこと。
それに加えて、javaでは多重継承は禁止しているため、それによって発生する問題(もう一つのクラスを取り込みたい)を解決できる機能とのこと
インターフェイスの宣言は以下のように、classをinterfaceに置き換えて記述する。
public interface クラス名 {
public abstract void メソッド名();
}
また、インターフェイスに宣言されたメソッドは自動的にpublicかつabstractになるというルールがあるので、public abstractは省略して以下の記述でも問題はないようである。
public interface クラス名 {
void メソッド名();
}
注意点
- インターフェイスを継承してクラスを定義するような場合、継承という言葉を用いず、インターフェイスを実装してクラスを作るという表現をする。
- インターフェイスの定義として挙げたように、基本的にフィールドを持たない。つまり変数を持つことは許されないが、例外的に定数だけはもつことを許される。
例えば以下のようにフィールドを宣言したとしても
public interface Circle {
double PI = 3.141592;
}
自動的にpublic static finalが補われ、以下と同等のコードになる
public interface Circle {
public static final double PI = 3.141592;
}
以下は実装に関する例
まずは使用するインターフェイスの宣言を以下とする。
public interface CleaningService {
Shirt washShirt(Shirt s);
Towl washTowl(Towl t);
Coat washCoat(Coat c);
}
このインターフェイスの中身は先ほど伝えたpublic abstractが省略された形式で記述されている抽象メソッドで、その抽象メソッドが3つ定義された状態である。
このインターフェイスを以下のクラスKyotoCleaningShopに実装させてクラスを定義します。
public class KyotoCleaningShop implements CleaningService {
String ownerName;
String address;
String phone;
/* シャツを洗う */
public Shirt washShirt(Shirt s) {
// 大型洗濯機15分
return s;
}
/* タオルを洗う */
public Towl washTowl(Towl t) {
// 大型洗濯機10分
return t;
}
/* コートを洗う */
public Coat washCoat(Coat c) {
// ドライ20分
return c;
}
}
上記例のコードのようにインターフェイスを実装するときはimplementsを用いる。
そして、抽象クラスで重要なのは継承した各抽象メソッドをオーバーライドしていることである。もし抽象メソッドをオーバーライドしていなければコンパイルエラーとなる。
最後にインターフェイスのクラス図(→は破線で表す)の記述例