ダイヤモンド継承でコンパイルエラーになる例
同じシグニチャを持つ複数のインターフェースをimplementsした場合、コンパイルエラーになります。
ifParent.java
public interface ifParent {
default void X(){
System.out.println("interfaseParent");
}
}
ifA.java
public interface ifA extends ifParent{
@Override
default void X(){
System.out.println("interfaseA");
}
}
ifB.java
public interface ifB extends ifParent{
@Override
default void X(){
System.out.println("interfaseB");
}
}
classC.java
public class classC implements ifA ,ifB { //ここでコンパイルエラーになる。
public static void main(String[] args) {
classC c = new classC();
c.X();
}
}
上記のソースをクラス図で表現すると以下のとおりです。
classCがifAとifBをimplementsしたタイミングでコンパイルエラーになります。
これはclassCから見た場合、ifAとifBが同階層にあり、両者ともdefaultメソッドをOverrideしているためです。
これを防ぐには以下のようにclassCでXメソッドをOverrideする必要があります。
classC.java
public class classC implements ifA ,ifB {
public static void main(String[] args) {
classC c = new classC();
c.X(); //classC
}
@Override
public void X(){
System.out.println("classC");
}
}
ダイヤモンド継承でコンパイルエラーにならない例
複数のインターフェースが同階層にあってもメソッドが異なる階層(距離が離れている場合)近いほうのメソッドが呼ばれるため、コンパイルエラーになりません。
ifParent.java
public interface ifParent {
default void X(){
System.out.println("interfaseParent");
}
}
ifA.java
public interface ifA extends ifParent{
@Override
default void X(){
System.out.println("interfaseA");
}
}
ifB.java
public interface ifB extends ifParent{
}
classC.java
public class classC implements ifA ,ifB {
public static void main(String[] args) {
classC c = new classC();
c.X(); //interfaseA
}
}
上記ソースをクラス図で表現すると以下のとおり。
ダイヤモンド継承でコンパイルエラーになる例との違いはifBでOverrideしていない点。
より近い方でOverrideしたifAのXメソッドが呼ばれます。
以上で記事の解説はお終い!
もっとJavaやSpringを勉強したい方にはUdemyがオススメ!同僚に差をつけよう!