Java Gold合格への道 ~defaultメソッド~
スポンサーリンク
こんにちは。たろすです。
今回はdefaultメソッドについて説明します。
defaultメソッドの使い方
defaultメソッドはインタフェースに記述します。
public interface A { default void methodA() { System.out.println("default method A"); } }
public class Impl implements A { }
public class Main { public static void main(String[] args) { Impl impl = new Impl(); impl.methodA(); } }
上から順に、インタフェース、実装クラス、メインクラスです。
実行すると次のような出力があります。
default method A
上記からわかるように、defaultメソッドはインタフェースにメソッドを実装することができます。
多重継承の場合は?
ここで多重継承の場合、両方のインタフェースに同じシグネチャのdefaultメソッドがある場合どうなるのか気になると思います。
例えば以下のような場合です。
public interface A { default void method() { System.out.println("default method A"); } }
public interface B { default void method() { System.out.println("default method B"); } }
public class Impl implements A, B { }
この場合、コンパイルエラーとなり、以下のようなメッセージが出力されます。
Exception in thread "main" java.lang.Error: Unresolved compilation problem: パラメーター () および () を持つ重複した default メソッド method は型 B および A から継承されています at defaultMethod.Impl.<init>(Impl.java:3) at defaultMethod.Main.main(Main.java:5)
一方で以下のような場合はコンパイルエラーになりません。
public interface A { default void method() { System.out.println("default method A"); } }
public interface B extends A { }
public interface C extends A{ default void method() { System.out.println("default method C"); } }
public class Impl implements B, C { }
これはなぜかと言うと、インタフェースCはmethod()をオーバーライドしているからです。
下の図を見てみましょう。
インタフェースBのmethod()は実際にはインタフェースAに実装されたmethod()です。
一方でインタフェースCのmethod()はC自身に実装されたmethod()です。
インタフェースAよりインタフェースCのmethod()のほうがImplクラスに距離が近いのでインタフェースCのmethod()が優先されます。