デフォルトメソッドの定義
デフォルトメソッドは、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 { }