デフォルトメソッドの導入により、Javaでも多重継承のようなことが可能になった。
しかし、同じメソッドを複数のインタフェースで定義し、それらを実装したクラスは作ることができない。次のコードはコンパイルエラーとなる。
interface Foo {
default void print() {
System.out.println(FOO);
}
}
interface Bar {
default void print() {
System.out.println(BAR);
}
}
// NG 同じメソッドを持つインタフェースは実装できない
class FooBar implements Foo, Bar { }
同じデフォルトメソッドを持つ複数のインタフェースを実装するには、デフォルトメソッドをオーバーライドする必要がある。
interface Foo {
default void print() {
System.out.println(FOO);
}
}
interface Bar {
default void print() {
System.out.println(BAR);
}
}
// OK 同じデフォルトメソッドを持つインタフェースは実装する場合
// デフォルトメソッドをオーバーライドする
class FooBar implements Foo, Bar {
@Override
public void print() {
System.out.println(FOOBAR);
}
}
実装クラスでインタフェースのデフォルトメソッドをコールしたい場合は、前述したようにインタフェース名とsuperを使用してコールする。
デフォルトメソッドを使用すると多重継承が可能となるが、同じシグネチャのメソッドを多重に継承できない。
ところで、インタフェースとクラスで同じメソッドを実装していた場合、それらを継承したクラスでは常にスーパークラスの実装が優先されるので可能である。
次のコードはコンパイル可能で、実行するとBARが出力される。
interface Foo {
default void print() {
System.out.println(FOO);
}
}
class Bar {
public void print() {
System.out.println(BAR);
}
}
class FooBar extends Bar implements Foo { }
public void test() {
FooBar foobar = new FooBar();
foobar.print();
}