Code Fix

上級

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パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)