Java
 Computer >> コンピューター >  >> プログラミング >> Java

Javaのオーバーライドでメソッドのシグネチャは変更できる?理由と具体例を解説


結論:オーバーライド時にシグネチャを変更することはできません

いいえ、できません。スーパークラスのメソッドをオーバーライドする際には、両者のメソッド名・パラメータ(引数の数と型)・戻り値の型がすべて同じである必要があります。これらが1つでも異なると、2つのメソッドは互いに無関係な別のメソッドとして扱われてしまいます。

つまり、シグネチャを変更した時点でオーバーライドは成立せず、意図どおりにサブクラスのメソッドが呼び出されない可能性があります。

スーパークラスのメソッドが実行される理由

シグネチャを変更すると、両者は「別々のメソッド」とみなされます。Javaでは、サブクラスのオブジェクトの中にスーパークラスのメソッドも引き継がれた形で存在するため、呼び出し時の引数に合致するスーパークラス側のメソッドが実行されてしまうのです。

具体例で確認する

次の例では、サブクラス側で第2引数の型だけを int から float へ変更しています。この結果、オーバーライドは失敗し、スーパークラスのメソッドが実行されます。

class Super {
    void sample(int a, int b) {
        System.out.println("スーパークラスのメソッド");
    }
}
public class MethodOverriding extends Super {
    // 第2引数の型が異なるため、オーバーライドではなくオーバーロードになる
    void sample(int a, float b) {
        System.out.println("サブクラスのメソッド");
    }
    public static void main(String args[]) {
        MethodOverriding obj = new MethodOverriding();
        obj.sample(20, 20);
    }
}

出力結果

スーパークラスのメソッド

なぜこうなるのか:オーバーロードとの関係

obj.sample(20, 20) の第2引数 20 はint型のリテラルです。そのため、引数の型が完全に一致するスーパークラスの sample(int, int) が選択されて実行されます。

一方、obj.sample(20, 20.5f) のようにfloat型の値を渡せば、今度はサブクラスの sample(int, float) が呼び出されます。

このように、パラメータを変えて定義したメソッドは、オーバーライドではなくオーバーロードとして扱われます。

ミスを防ぐためのポイント

  • @Overrideアノテーションを付ける: オーバーライドを意図するメソッドには必ず @Override を付けましょう。シグネチャが一致していない場合にコンパイルエラーで通知されるため、上記のようなミスを未然に防げます。
  • 戻り値の型について: 厳密にはJava 5以降、戻り値の型はスーパークラスのメソッドと同じ型、またはそのサブタイプ(共変戻り値型)であれば許容されます。ただし、パラメータは完全に一致させる必要があります。

  1. Javaの列挙型(enum)は任意のクラスを拡張できる?継承の仕組みを解説

    Javaの列挙型(enum)とは列挙型(enum)は、Javaにおいて定数の集合を格納するためのデータ型です。1週間の曜日や1年の月名など、固定された値のグループを扱う際に活用されます。列挙型を定義するには、enumキーワードの後に列挙型の名前を続けて記述します。enum Days { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY }配列と同様に、列挙型内の要素(定数)には0から始まる番号が自動的に割り当てられます。上記の例では、各曜日が以下の図のように番号で識別されます。列挙型はクラスとよく似た構造を持ち

  2. Javaのメソッドオーバーライドとは?仕組みとサンプルコードを解説

    オーバーライドとはオーバーライド(Override)とは、サブクラスが親クラスから継承したメソッドを、自身の要件に合わせて再定義できる機能です。これにより、サブクラスはその型に固有の振る舞いを実装することができます。オブジェクト指向の観点で言えば、オーバーライドとは「既存のメソッドの機能を上書きする」ことを意味します。オーバーライドの例具体的な例を見てみましょう。以下のコードでは、Animal クラスの move() メソッドを、Dog クラスがオーバーライドしています。class Animal {    public void move() {&nbs