サイトアイコン プログラマー(PG)・システムエンジニア(SE)になるための入門講座

【Java初心者向け】オーバーロードとオーバーライドの違いとは?見分け方と使い分けを解説

【Java初心者向け】オーバーロードとオーバーライドの違いとは?見分け方と使い分けを解説

結論として、オーバーロードは「同じクラス内などで、同じメソッド名を引数違いで複数定義すること」、オーバーライドは「親クラスのメソッドを子クラスで上書きすること」です。

名前が似ているため混同しやすいですが、目的も成立条件も異なります。

比較項目 オーバーロード オーバーライド
主な意味 同名メソッドを複数用意する 親クラスの処理を子クラスで上書きする
英語 Overload Override
引数 異なる必要がある 基本的に同じ
継承 必須ではない 必要
主な目的 呼び出し方を増やす クラスごとに処理を変更する

オーバーロードとは

オーバーロードとは、同じメソッド名で、引数の数や型が異なるメソッドを複数定義する仕組みです。

日本語では「多重定義」と呼ばれることがあります。

class Calculator {

    int add(int a, int b) {
        return a + b;
    }

    int add(int a, int b, int c) {
        return a + b + c;
    }

    double add(double a, double b) {
        return a + b;
    }
}

上記では、addという同じメソッド名を使用していますが、引数が異なるため別のメソッドとして扱われます。

オーバーライドとは

オーバーライドとは、親クラスで定義されたメソッドを、子クラスで同じ形のまま再定義する仕組みです。

日本語では「上書き」と説明されることが多くあります。

class Employee {

    void work() {
        System.out.println("仕事をします");
    }
}

class Engineer extends Employee {

    @Override
    void work() {
        System.out.println("システムを開発します");
    }
}

Engineerクラスでは、親クラスEmployeeのworkメソッドをオーバーライドしています。

オーバーロードとオーバーライドの違い

比較項目 オーバーロード オーバーライド
定義場所 同じクラス内が一般的 親クラスと子クラス
メソッド名 同じ 同じ
引数の数 異なってよい 同じ
引数の型 異なってよい 同じ
戻り値 戻り値だけ変えても成立しない 同じ型または互換性のある型
継承関係 不要 必要
判定時期 主にコンパイル時 主に実行時

どんな場面で使われるのか

オーバーロードを使う場面

オーバーライドを使う場面

なぜ重要なのか

オーバーロードを使うと、似た役割のメソッド名を統一できるため、利用する側が覚えやすくなります。

一方、オーバーライドを使うと、親クラスを共通の型として扱いながら、実際の処理だけを子クラスごとに変更できます。

この仕組みは、オブジェクト指向の重要な考え方であるポリモーフィズム(多態性)につながります。

初心者が混乱しやすいポイント

どちらもメソッド名が同じ

オーバーロードとオーバーライドは、どちらも同じメソッド名を使います。

見分けるときは、引数が違うのか、継承先で上書きしているのかを確認します。

戻り値だけを変えてもオーバーロードにならない

次のように、戻り値だけが異なるメソッドは定義できません。

int getValue() {
    return 1;
}

double getValue() {
    return 1.0;
}

Javaは呼び出し時に戻り値だけでメソッドを区別できないため、コンパイルエラーになります。

引数名を変えてもオーバーロードにならない

void print(String name) {
}

void print(String message) {
}

引数名がnameとmessageで異なっていても、どちらもString型を1つ受け取るため、同じメソッドと判断されます。

オーバーロードが成立する条件

オーバーロードを成立させるには、メソッド名を同じにしたうえで、次のいずれかを変更します。

void register(String name) {
}

void register(String name, int age) {
}

void register(int id, String name) {
}

void register(String name, int id) {
}

ただし、引数の並び順だけを変える方法は、呼び出す側が混乱しやすいため、実務では慎重に使用します。

オーバーライドが成立する条件

オーバーライドでは、親クラスのメソッドと次の内容を合わせる必要があります。

また、子クラス側で親クラスよりアクセス範囲を狭くすることはできません。

親クラス 子クラス 結果
public public
protected public
public protected ×

@Overrideを付ける理由

オーバーライドするメソッドには、@Overrideアノテーションを付けるのが基本です。

@Override
void work() {
    System.out.println("システムを開発します");
}

@Overrideを付けると、メソッド名や引数を間違えた場合にコンパイラが検出してくれます。

付けなくても条件を満たせばオーバーライドは成立しますが、入力ミスを防ぐため、実務では付けることが推奨されます。

実際のIT現場での利用例

オーバーロードの利用例

ログ出力処理では、通常メッセージだけを渡す場合と、例外情報も一緒に渡す場合があります。

void writeLog(String message) {
    System.out.println(message);
}

void writeLog(String message, Exception exception) {
    System.out.println(message);
    exception.printStackTrace();
}

オーバーライドの利用例

通知システムでは、通知方法ごとにsendメソッドの処理を変更できます。

class Notification {

    void send() {
        System.out.println("通知します");
    }
}

class EmailNotification extends Notification {

    @Override
    void send() {
        System.out.println("メールを送信します");
    }
}

class ChatNotification extends Notification {

    @Override
    void send() {
        System.out.println("チャットへ送信します");
    }
}

筆者が実際に経験した失敗例

新人時代、親クラスのメソッドをオーバーライドしたつもりで、引数の型を間違えて定義したことがありました。

実際にはオーバーライドではなく、新しいオーバーロードとして扱われていたため、親クラスの処理がそのまま実行されました。

@Overrideを付けたところ、コンパイル時に誤りを検出できました。それ以降、オーバーライドするメソッドには必ず@Overrideを付けています。

業務でよくあるトラブル例

原因の切り分け

期待したメソッドが呼び出されない場合は、次の順番で確認します。

  1. 実際に生成されているオブジェクトのクラスを確認する
  2. メソッド名が一致しているか確認する
  3. 引数の数と型を確認する
  4. @Overrideが付いているか確認する
  5. 親クラスと子クラスの継承関係を確認する
  6. IDEのデバッグ機能で実行されるメソッドを確認する

GUIでの確認方法

IntelliJ IDEAやEclipseでは、メソッド名の横に表示されるアイコンから、親クラスや子クラスのメソッドへ移動できます。

よく使うショートカットキー

操作 IntelliJ IDEA Eclipse
定義へ移動 Ctrl + B F3
実装へ移動 Ctrl + Alt + B Ctrl + T
呼び出し階層 Ctrl + Alt + H Ctrl + Alt + H

macOSでは、Ctrlの代わりにCommandやOptionを使用する場合があります。

CUIでの確認方法

Javaのコンパイル結果やテスト結果は、コマンドからも確認できます。

オーバーライド条件を満たしていない場合、@Overrideを付けていればコンパイルエラーとして検出されます。

ログの確認方法

どのメソッドが実行されているか分からない場合は、クラス名とメソッド名をログへ記録します。

System.out.println("EmailNotification.sendを実行しました");

実務では、System.out.printlnではなく、プロジェクトで採用されているログ出力ライブラリを使用します。

ログでは次の内容を確認します。

確認結果の見方

確認結果 判断
同名で引数が異なる オーバーロード
親子関係があり、同じ引数で再定義 オーバーライド
戻り値だけが異なる コンパイルエラー
@Overrideでエラーになる メソッド名や引数が親クラスと一致していない可能性

初心者がやりがちなミス

注意点

privateメソッドは子クラスから直接見えないため、オーバーライドできません。

また、finalが付いたメソッドもオーバーライドできません。

メソッド オーバーライド
publicメソッド 可能
protectedメソッド 可能
privateメソッド 不可
finalメソッド 不可
staticメソッド 通常のオーバーライドではない

上司へ報告するポイント

エスカレーションするタイミング

応用知識

ポリモーフィズムとの関係

オーバーライドを利用すると、親クラス型の変数に異なる子クラスのオブジェクトを代入し、それぞれ異なる処理を実行できます。

Notification notification = new EmailNotification();
notification.send();

変数の型はNotificationですが、実際のオブジェクトはEmailNotificationのため、EmailNotificationでオーバーライドしたsendメソッドが実行されます。

コンストラクタのオーバーロード

コンストラクタも引数を変えることでオーバーロードできます。

class User {

    User() {
    }

    User(String name) {
    }

    User(String name, int age) {
    }
}

一方、コンストラクタは継承されないため、オーバーライドはできません。

関連するIT用語

よくある質問(FAQ)

オーバーロードとオーバーライドの簡単な覚え方はありますか?

オーバーロードは「同じ名前のメソッドを追加する」、オーバーライドは「親の処理を上書きする」と覚えると区別しやすくなります。

戻り値を変えるだけでオーバーロードできますか?

できません。オーバーロードでは、引数の数、型、並び順のいずれかを変える必要があります。

@Overrideは必須ですか?

文法上は必須ではありませんが、入力ミスをコンパイル時に発見できるため、付けるのが基本です。

staticメソッドはオーバーライドできますか?

通常の意味でのオーバーライドはできません。子クラスで同じ形のstaticメソッドを定義した場合は、メソッドの隠蔽と呼ばれます。

privateメソッドはオーバーライドできますか?

できません。privateメソッドは子クラスから参照できないため、同名メソッドを定義しても別のメソッドとして扱われます。

まとめ

オーバーロードとオーバーライドは、どちらも同じメソッド名を使いますが、目的と成立条件が異なります。

見分けるときは、「引数違いで同名メソッドを増やしているのか」「親クラスの処理を子クラスで上書きしているのか」を確認しましょう。この違いを理解すると、Javaの継承やポリモーフィズムも理解しやすくなります。

モバイルバージョンを終了