【Java】間違いやすい! オーバーロード と オーバーライド の違い


はじめに

Java を勉強しているとぶち当たる壁。
そう、「オーバーロード」と「オーバーライド」の違いです。

今回は、混同しやすいこの2つの用語について、私が「あ!なんかわかったかも!」と思えたイメージを紹介したいと思います。

前提

なるべく本筋である「オーバーロード」と「オーバーライド」の違いが伝わりやすいように、説明がそれすぎないよう心がけています。

なので、これから説明に出てくる用語(例えば「メソッド」「コンストラクタ」「継承」など)については、この記事では1から説明はしていません。

そんな用語まったくわからない!聞いたこともない!という方にとっては混乱を増やしてしまうだけかもしれませんが、そのあたりご理解いただいた上で読んでいただけると幸いです

まず結論から

オーバーロード は「元々あるメソッドが使える道を増やす
オーバーライド は「元々あるメソッドの上に乗って上書きする

これだけでは、え、どういうこと…?と思いますよね。
まず、それぞれどういう意味なのか見ていきましょう。

【オーバーロード】

同じメソッドの名前を特定の条件下で別のメソッドとして定義する。
キーワード:メソッド、戻り値、引数、コンストラクタ

使う時の注意ポイント

↓ をどちらも満たしていることが、オーバーロードできる条件
メソッド名戻り値の型一緒
引数の並び順 or or 違う

どんな時に使うもの?

オーバーロードは、似たような処理だけどちょっとだけ変えて別のメソッドにしたいという時に便利です。

例えば、商品を購入するときの表示を考えるとしましょう。
最終的に、

タナカさんお買い上げありがとうございます  // ★
500円です  // ◆

と表示させたいとしましょう。
★と◆で人によって変わりそう(その時によって変わりそう)な部分はどこでしょう?
★だとタナカという名前、◆だと500という金額が変わりそうな部分ですよね。
あとは使いまわしても大丈夫そうです。

今回は、表示させるメソッド display() に、その時々で変わりそうな部分を引数として渡すことにします。
★名前は文字列なので String型 にします。
◆金額を表示したいときは、計算が必要そうなので int型 にしておきましょう。

Overroad.java
public class Overroad{
    // ★を表示するメソッド
    static void display(String moji){
        System.out.println(moji + "さんお買い上げありがとうございます");
    }

    // ◆を表示するメソッド
    static void display(int goukeiKingaku){
        System.out.println(goukeiKingaku + "円です");
    }

    // メイン処理
    public static void main (String[] args){

        int itemPrice1 = 200;
        int itemPrice2 = 300;
        int sumPrice = itemPrice1 + itemPrice2;

        // ★を表示するメソッド呼び出し
        display("タナカ");
        // ◆を表示するメソッド呼び出し
        display(sumPrice);
    }
}

↓ 実行してみます

> java Overroad        
タナカさんお買い上げありがとうございます
500円です

このように、「同じような処理なんだけどちょっと変えて別のことしたいんだよな~」という時に便利なのがオーバーロードです。

同じ名前のメソッドでありながらまったく別のメソッドを作るという特徴と ロード という名前から、私には「元々あるメソッドが使える道を増やす」イメージがしっくりときました。
↓ イラストにするとこんな感じ ↓

ちなみに、この例ではメソッド名を変えればよさそうですが、そうもいかないときがあります。
それがコンストラクタです。
コンストラクタは、クラス名と同じメソッド名でなければないので、オーバーロードとの相性が良いのです。
詳しく知りたい方は「Java コンストラクタ オーバーロード」でググってみたりと、調べてみると面白いと思います

【オーバーライド】

継承関係がある親クラスのメソッドを、子クラスで上書きする。
キーワード:継承、メソッド

使う時の注意ポイント

メソッド名戻り値の型引数の並び順 or or 一緒

どんな時に使うもの?

オーバーライドは、親クラスのメソッドの中身をちょっと変えたいときに便利です。

例えば、プログラミングを始めると一度は目にしたことあるであろう「Hello World」の表示を、少し変更したいとします。
今回のゴールは、

Konnichiwa World

を表示することです。
「Hello World」を表示させていたのですが、その後ユーザーから「Hello は日本語ではなんて言うの?」と言われたんですかね。
子クラスでは親クラスのメソッドをちょちょっと直すだけで「Konnichiwa World」にしてみます。

Override.java
// 親クラス
class OyaClass {
    public static void display(String name){
        System.out.println("Hello " + name);
    }
}

//子クラス
class KoClass extends OyaClass{
    // 親クラスからオーバーライドするメソッド
    public static void display(String name){
        System.out.println("Konnichiwa " + name);
    }
}

public class Override{
    // メイン処理
    public static void main (String[] args){
        // サブクラスのインスタンスを作成
        KoClass koClass = new KoClass();
        // オーバーライドしたメソッド呼び出し
        KoClass.display("World");
    }
}

↓ 実行してみます

> java Override        
Konnichiwa World

オーバーライドされたメソッドは、子クラスのメソッドから使われるという決まりがあるので、無事に日本語的な挨拶を表示することができました。

親クラスのメソッドを使いまわしつつ、ちょっとだけ処理内容を変えるという特徴と ライド という名前から、私には「元々あるメソッドの上に乗って上書きする」イメージがしっくりときました。
↓ イラストにするとこんな感じ ↓

まとめ

オーバーロード
同じメソッドの名前を特定の条件下で別のメソッドとして定義する。
「元々あるメソッドが使える道を増やす」イメージ。
同じ名前だけど別のメソッドを作りたい時に便利。

オーバーライド
継承関係がある親クラスのメソッドを、子クラスで上書きする。
「元々あるメソッドの上に乗って上書きする」イメージ。
親クラスのメソッドの中身を少し変えたい時に便利。

参考

【Java入門】オーバーロードの使い方(オーバーライドとの違いも解説)
【Java入門】オーバーライド(Override)の使い方

さいごに

なんでこんなに似ている名前をつけるのか…
紛らわしい用語ですが、自分がしっくり来る例やイメージと出会えるとぐっと理解しやすくなると思います。
ぴったりなイメージが見つかるまで、とりあえずの参考になればと思います