default メソッドの衝突と解決
複数のインターフェースから同名を継承すると衝突します。A.super.name() による明示的な選択を扱います。
エラーメッセージの読み方
Main.java:2: error: interface abstract methods cannot have body
Main.java- ファイル名
2- 行番号 — javacが異常に気づいた位置。原因の行とは限りません
error- 種別 — コンパイルエラー。実行まで到達しません
interface abstract methods cannot have body- 内容 — javacが期待していたもの、または見つけられなかったもの
このエラーが出る典型パターン
パターン1
1 interface Greeter { 2 void greet() { System.out.println("hi"); } ^ 3 } 4 public class Main implements Greeter { 5 public static void main(String[] args) { 6 new Main().greet(); 7 } 8 }
Main.java:2: error: interface abstract methods cannot have body
インターフェースで実装を持たせるにはdefaultを付けます。付けない宣言は本体を持てません。
直し方: (空) を default にします。
広告
広告スロット(未設定)
パターン2
1 interface A { default String name() { return "A"; } } 2 interface B { default String name() { return "B"; } } 3 public class Main implements A, B { 4 ^ 5 public static void main(String[] args) { 6 System.out.println(new Main().name()); 7 } 8 }
Main.java:3: error: class Main inherits unrelated defaults for name() from types A and B
同名のdefaultメソッドを複数継承すると衝突します。実装クラスで上書きし、A.super.name() で明示的に選びます。
直し方: (空) を public String name() { return A.super.name(); } にします。
よくある誤解
defaultは既存の実装を壊さずにメソッドを追加するための仕組みです。設計の便利機能として使うと衝突します。
まとめ
default メソッドの衝突と解決は上級でつまずきやすい項目です。上の2パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。