Java8から新しく追加されたインタフェースのデフォルトメソッド。
デフォルトメソッドの定義
デフォルトメソッドは、defaultキーワードと共にメソッドを宣言します。
この例では、printメソッドがデフォルトメソッドとして宣言されています。
interface Hoge {
default void print() {
System.out.println("hoge");
}
}
同じデフォルトメソッドを持つ複数のインタフェースを実装した場合
何もしなければコンパイルエラーとなります。
例えば、下のコードではImplクラスが同じ定義のデフォルトメソッドを持つI1とI2インターフェースを実装しているので、コンパイル時にエラーとして報告されます。
interface I1 {
default void print() {
System.out.println("I1");
}
}
interface I2 {
default void print() {
System.out.println("I2");
}
}
class Impl implements I1, I2 {
}
もしどちらか一方の実装を使用したいのであれば、superキーワードを使用して一方のインタフェースの実装を選択します。
下の例では、I2インタフェースのデフォルト実装を選択しています。
class Impl implements I1, I2 {
@Override
public void print() {
I2.super.print();
}
}
もちろん、下のコードのように実装を上書きすることもできます。
class Impl implements I1, I2 {
@Override
public void print() {
System.out.println("Impl");
}
}
片方がデフォルトメソッドで片方が抽象メソッドの場合も、コンパイルエラーとなります。
この場合も、上で説明したようにデフォルトメソッドを選択するか、このクラスで新たな実装をするか選択する必要があります。
interface I1 {
default void print() {
System.out.println("I1");
}
}
interface I2 {
void print();
}
class Impl implements I1, I2 {
}
一方が抽象クラスの場合には、抽象クラスに定義されたメソッドが優先されて選択されます。
例えば下のコードの場合、A1抽象クラスに定義されたprintメソッドが呼び出されます。
interface I1 {
default void print() {
System.out.println("I1");
}
}
abstract class A1 {
public void print() {
System.out.println("A1");
}
}
class Impl extends A1 implements I1 {
}