【Java】 オーバーライド エラーについて
Javaにおけるオーバーライドは、サブクラスがスーパークラスのメソッドを再定義する仕組みです。しかし、正しくオーバーライドしない場合、コンパイルエラーや実行時エラーが発生することがあります。このページでは、オーバーライドエラーの原因と解決方法を例とともに解説します。
オーバーライドとは
Javaにおけるオーバーライド(Override)とは、サブクラスがスーパークラスで定義されたメソッドを再定義することです。これにより、ポリモーフィズム(多態性)が可能となり、サブクラス独自の振る舞いを指定できます。
オーバーライドの基本的なルールは以下の通りです:
- メソッド名、引数リスト、戻り値の型がスーパークラスのメソッドと同一でなければなりません。
- アクセス修飾子はスーパークラスのメソッドと同じか、より広い範囲にする必要があります。
- スーパークラスのメソッドが例外をスローする場合、サブクラスのメソッドは同じ例外か、それよりも派生した例外しかスローできません。
- @Overrideアノテーションを使用すると、オーバーライドが正しく行われていることをコンパイラが検証します。
オーバーライドエラーの一般的な原因
オーバーライドエラーの原因として以下のものが挙げられます:
- メソッドシグネチャが一致していない – メソッド名や引数が異なる場合、別のメソッドとして扱われます。
- アクセス修飾子の制限 – サブクラスのメソッドがスーパークラスのメソッドよりも狭いアクセス修飾子を持っている場合にエラーになります。
- 例外の不一致 – スーパークラスのメソッドがスローする例外よりも広範な例外をスローするとエラーになります。
- staticメソッドの誤使用 – staticメソッドはオーバーライドではなく、隠蔽(hiding)されます。
- @Overrideアノテーションの未使用 – 人為的ミスによる誤りを防ぐため、@Overrideアノテーションを付けることが推奨されます。
具体例と解決策
メソッドシグネチャの不一致
// スーパークラス
class Parent {
void display(String message) {
System.out.println("Parent: " + message);
}
}
// サブクラス(誤りあり)
class Child extends Parent {
// メソッド名が異なる
void Display(String message) {
System.out.println("Child: " + message);
}
}
上記の例では、サブクラスのメソッド名が大文字小文字で異なるため、別のメソッドとして扱われ、オーバーライドされません。
解決策:メソッド名を正確に一致させます。
class Child extends Parent {
@Override
void display(String message) {
System.out.println("Child: " + message);
}
}
アクセス修飾子の制限
// スーパークラス
class Parent {
protected void show() {
System.out.println("Parent show");
}
}
// サブクラス(誤りあり)
class Child extends Parent {
// エラー: アクセス修飾子が狭い
void show() {
System.out.println("Child show");
}
}
上記の例では、スーパークラスのメソッドがprotectedであるのに対し、サブクラスのメソッドがデフォルトアクセスになっているためエラーになります。
解決策:アクセス修飾子を広げます。
class Child extends Parent {
@Override
public void show() {
System.out.println("Child show");
}
}
例外の不一致
// スーパークラス
class Parent {
void process() throws Exception {
System.out.println("Parent process");
}
}
// サブクラス(誤りあり)
class Child extends Parent {
// エラー: より広範な例外をスローしている
@Override
void process() throws Throwable {
System.out.println("Child process");
}
}
スーパークラスのメソッドがthrows Exceptionとしているのに対し、サブクラスのメソッドがthrows Throwableとしているためエラーになります。
解決策:例外をスーパークラスと一致させるか、派生例外に制限します。
class Child extends Parent {
@Override
void process() throws Exception {
System.out.println("Child process");
}
}
staticメソッドの誤使用
// スーパークラス
class Parent {
static void print() {
System.out.println("Parent print");
}
}
// サブクラス
class Child extends Parent {
// staticメソッドはオーバーライドではなく隠蔽される
static void print() {
System.out.println("Child print");
}
}
public class Main {
public static void main(String[] args) {
Parent p = new Child();
p.print(); // "Parent print" が出力される
}
}
上記の例では、staticメソッドが隠蔽されるため、実行結果はスーパークラスのメソッドが呼び出されます。
解決策:staticメソッドのオーバーライドはできないため、非staticメソッドを使用します。
まとめ
Javaのオーバーライドエラーは、メソッドシグネチャの不一致、アクセス修飾子の制限、例外の不一致、staticメソッドの誤使用などが主な原因です。@Overrideアノテーションを活用し、オーバーライドが正しく行われているかをコンパイラに確認させることで、エラーを防ぐことができます。