Java interfaceとは、定数と継承クラスが実装すべきメソッドの宣言を集めたものです。クラスが備えるべきインタフェースを簡潔に表現できるうえ、多重継承もできるメリットがあります。
インタフェースとは定数とメソッドの宣言だけを集めたものである。Javaにおいてインタフェースの宣言は次の書式で行う。
[public] interface InterfaceName { ... }
インタフェース内で定数を定義できる。インタフェース内で定数を定義する場合、public、static および final 修飾子は省略できる。
interface Node {
short ELEMENT_NODE = 1;
short ATTRIBUTE_NODE = 2;
short TEXT_NODE = 3;
}
インタフェースはインタフェースを継承することができる。
interface Element extends Node {
String getAttribute(String qualifiedName);
void setAttribute(String qualifiedName, String value);
}
Javaのクラスは複数のクラスを継承できないが、Javaのインタフェースは複数のインタフェースを継承することができる。複数のインタフェースを継承することを「多重継承」と呼ぶ。
インタフェースを多重継承するには、継承するインタフェースをカンマで区切って、複数のインタフェースを指定する。
interface FooIf {
void foo();
}
interface ExampleConstants {
public static final double PI = 3.14;
}
interface ExampleIf extends FooIf, ExampleConstants {
/* 定数の定義 */
/* メソッドの宣言 */
}
クラスがインタフェースを継承することを「実装」と呼ぶ。
インタフェースの実装は、implements キーワードを使用する。
class Example implements ExcampleIf {
public void foo() {
// do something
}
}
クラスを継承するときの extends
とは異なります。
Java SE 7までのインタフェースに定義できるメソッドは抽象メソッドのみであったが、Java SE 8のインタフェースから具象メソッドも定義できるようになった。
Javaのインタフェースで具象メソッドを定義するには、default キーワードを指定する。
public interface ExampleIf {
void setId(int id);
default int getId() {
return 0;
}
}
インタフェースと似たものに 抽象クラス がある。インタフェースと抽象クラスの違いを次に示す。
インタフェース | 抽象クラス | |
---|---|---|
インスタンス化できるか | No | No |
継承するときのキーワード | implements | extends |
サブクラスが多重継承できるか | Yes | No |
抽象メソッドを宣言できるか | Yes | Yes |
具象メソッドを定義できるか | Yes | Yes |
final変数を定義できるか | Yes | Yes |
非final変数を定義できるか | No | Yes |
インタフェースで変数を定義することはできるが、暗黙的に修飾子が public static final となる制限がある。
インタフェースに final
修飾子を付けることはできない。インタフェースはサブクラスによって継承(実装)されることを前提としているが、final
修飾子はそれを禁止するため、矛盾するからである。
Oracle (2021) "Interfaces" The Java™ Tutorials
ぺけみさお (2013) Javaで定数を定義するには定数クラスを使おう