Code Fix

上級

is not abstract and does not override の原因と直し方

抽象メソッドの実装漏れ。extendsとimplementsの使い分け、可視性の制約も扱います。

エラーメッセージの読み方

Main.java:4: error: Main is not abstract and does not override abstract method area() in Shape
Main.java
ファイル名
4
行番号 — javacが異常に気づいた位置。原因の行とは限りません
error
種別 — コンパイルエラー。実行まで到達しません
Main is not abstract and does not override abstract method area() in Shape
内容 — javacが期待していたもの、または見つけられなかったもの

このエラーが出る典型パターン

パターン1

 1  abstract class Shape {
 2      abstract double area();
 3  }
 4  public class Main extends Shape {
 5                                   
                      ^
 6      public static void main(String[] args) {
 7          System.out.println(new Main().area());
 8      }
 9  }
Main.java:4: error: Main is not abstract and does not override abstract method area() in Shape

抽象メソッドは具象クラスで必ず実装します。実装しないならクラス自体もabstractにします。

直し方: (空) を double area() { return 1.0; } にします。

この問題を解いてみる →

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

パターン2

 1  interface Greeter {
 2      void greet();
 3  }
 4  public class Main extends    Greeter {
                           ^
 5      public void greet() { System.out.println("hi"); }
 6      public static void main(String[] args) {
 7          new Main().greet();
 8      }
 9  }
Main.java:4: error: no interface expected here

クラスの継承はextends、インターフェースの実装はimplementsです。多重に実装できるのは後者だけです。

直し方: extends を implements にします。

この問題を解いてみる →

パターン3

 1  interface Greeter {
 2      void greet();
 3  }
 4  public class Main implements Greeter {
 5                void greet() { System.out.println("hi"); }
            ^
 6      public static void main(String[] args) {
 7          new Main().greet();
 8      }
 9  }
Main.java:5: error: greet() in Main cannot implement greet() in Greeter attempting to assign weaker access privileges; was public

インターフェースのメソッドは暗黙にpublicです。実装側でpublicを省くとパッケージ内限定になり狭まります。

直し方: (空) を public にします。

この問題を解いてみる →

パターン4

 1  abstract class Shape {
 2      abstract double area();
 3      abstract double perimeter();
 4  }
 5  public class Main extends Shape {
 6      double area() { return 4.0; }
 7                                        
                         ^
 8      public static void main(String[] args) {
 9          System.out.println(new Main().area());
10      }
11  }
Main.java:5: error: Main is not abstract and does not override abstract method perimeter() in Shape

抽象メソッドは1つでも実装し忘れると、そのクラス全体が具象クラスとして認められません。

直し方: (空) を double perimeter() { return 8.0; } にします。

この問題を解いてみる →

パターン5

 1  import java.io.IOException;
 2  abstract class Loader {
 3      abstract void load() throws IOException;
 4  }
 5  public class Main extends Loader {
 6      void load() throws Exception        { }
                                   ^
 7      public static void main(String[] args) throws Exception {
 8          new Main().load();
 9      }
10  }
Main.java:5: error: load() in Main cannot override load() in Loader

オーバーライドでは親より広い検査例外を新たに投げることはできません。宣言する例外は親と同じか、より狭い範囲にします。

直し方: Exception を IOException にします。

この問題を解いてみる →

よくある誤解

エラーは実装が漏れているクラス側に出ます。抽象メソッドを追加した親クラス側ではありません。

実務での勘所

このエラーが起きるのは、実装が必須の抽象メソッド(abstractメソッドや、defaultを付けていないインターフェースメソッド)を実装していない場合だけです。Java 8以降のインターフェースはdefaultメソッドを持てるようになり、defaultを付けたメソッドは実装クラス側でオーバーライドしなくてもコンパイルが通ります。「インターフェースのメソッドは全部実装が必須」という理解は、Java 7以前では正しくてもJava 8以降は正確ではありません。

演習をはじめる

関連するエラー

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