Java
2022.02.14
Javaのオーバーロードとは?オーバーライドとの違いや使い方をわかりやすく解説!
2023.11.15

Javaで開発を進めていくと、「オーバーロード」という単語を聞くことも多いのではないでしょうか。実はとても身近なところで使われているのです。


この記事では、オーバーロードの使い方やメリット、よく間違えられる「オーバーライド」との違いなどを詳しく解説していきます。


1.Javaのオーバーロードとは?

オーバーロードとは、メソッドやコンストラクタを多重に定義することです。

宣言の際に指定する引数の個数、型が異なっていれば、同じ名前で複数のメソッド、コンストラクタを定義できます。

①オーバーロードするメリット

では、同じ名前のメソッドを複数定義できるとどのようなメリットがあるのでしょうか。


オーバーロードが使われている身近な例の一つに「System.out.println()」があります。printlnメソッドは、int, double, Stringなど引数の型が違っても同じメソッド名で使用できますよね。


これは引数の型が違うprintlnメソッドが多重に定義されている、つまりオーバーロードが使われているからなのです。


このように、オーバーロードすれば引数によってメソッドの名前を少しずつ変更する必要がなく、メソッド名を覚える必要もなくなる、など様々なメリットがあります。

②オーバーロードするデメリット

オーバーロードの使い方によってはデメリットも存在します。


たくさんオーバーロードしすぎた場合、プログラムの理解がしにくく管理が難しくなってしまいます。またしっかりと設計しないと、同じ名前でもばらばらの処理を行うメソッドが生まれてしまったりして、混乱を招いてしまうこともあるでしょう。


オーバーロードは便利ですが、何にでも使えばいいわけではありません。必要なところを見極めて使用しましょう。

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


オーバーライドとは、スーパークラスのメソッドをサブクラスで再定義し直すことです。


クラスの継承を行うと、継承元であるスーパークラスのメソッドは、継承先であるサブクラスでそのまま使用できます。しかしそれをサブクラスで再定義、すなわちオーバーライドすることで、サブクラスに適したメソッドに変えられるのです。


オーバーロードと名前は似ていますが、


・オーバーロード:クラス内でメソッドを多重に定義すること

・オーバーライド:継承元のクラスのメソッドを継承先のクラスで再定義すること

とまったく違うことがわかります。


オーバーライドもオブジェクト指向プログラミングでよく使われるので、違いを理解しておきましょう。



3.オーバーロードの使い方


次に、実際にどうやってオーバーロードを使うのかを解説していきます。


構文だけでなく、使うための条件もしっかり把握しておきましょう。

①オーバーロードの基本構文

オーバーロードの基本構文は以下の通りです。

public static 戻り値の型 メソッド名(データ型 引数1, データ型 引数2 ……) {
    処理;
}

public static 戻り値の型 メソッド名(データ型 引数1, データ型 引数2, データ型 引数3 ……) { // 引数の数、型、順番のいずれかが異なる必要あり
    処理;
}

同じ名前のメソッドを複数宣言するだけなので、難しく考える必要はありません。ただし、引数の数、型、順番のいずれか1つは必ず異なっていなければならないという条件があります。この条件を満たせばいくつでも多重に定義できます。


実際にオーバーロードを使ってみましょう。

public class Java_overload {
    public static void main(String[] args) {
        System.out.println(add(1, 2)); // (1)が呼び出される
        System.out.println(add(1, 2, 3)); // (2)が呼び出される
    }

    public static int add(int x, int y) { // (1)引数が2つ
        int num = x + y;
        return num;
    }

    public static int add(int x, int y, int z) { // (2)引数が3つ
        int num = x + y + z;
        return num;
    }
}

出力:

3
6

引数を足し合わせるメソッド「add」を多重定義しました。ここでは(1)int型の引数を2つ受け取り足し合わせるaddメソッド、(2)int型の引数を3つ受け取り足し合わせるaddメソッドの2種類が存在します。


この2種類は、呼び出す際に指定される引数によって自動的に使い分けられるのです。

②オーバーロードの条件

次に、「引数の数、型、順番のいずれか1つは異なる必要がある」という条件について、詳しく解説していきます。


ここで「シグネチャ」という単語について紹介します。


シグネチャとは、メソッド名と引数の形(引数の数、型、順番など)を合わせた部分のことで、addメソッドでいえば「add(int x, int y)」の部分です。


メソッドを宣言する際、同じクラス内ではシグネチャが重複してはいけないという決まりがあり、オーバーロードするときにもこれを守らなければなりません。


オーバーロードを行うときにはシグネチャのうちメソッド名の部分はすでに重複しているので、引数の形を重複させないことが必要になります。そのため「引数の数、型、順番のいずれか1つは異なる必要がある」という条件があるのです。


以下のソースコードを見てみましょう。

public static void main(String[] args) {
    System.out.println(add(1, 2));      // (1)が呼び出される
    System.out.println(add(1.2, 3.4));  // (2)が呼び出される
    System.out.println(add(1, 2, 3));   // (3)が呼び出される
    System.out.println(add(1, 2.3));    // (4)が呼び出される
    System.out.println(add(1.2, 3));    // (5)が呼び出される
}

public static int add(int x, int y) { // (1) int, int
    int num = x + y;
    return num;
}

public static double add(double x, double y) { // (2) double, double
    double num = x + y;
    return num;
}

public static int add(int x, int y, int z) { // (3) int, int, int
    int num = x + y + z;
    return num;
}

public static double add(int x, double y) { // (4) int, double
    double num = x + y;
    return num;
}

public static double add(double x, int y) { // (5) double, int
    double num = x + y;
    return num;
}

出力:

3
4.6
6
3.3
4.2

引数の数が異なる場合というのは、(3)のような場合です。(1)、(2)、(4)、(5)は引数が2つですが、(3)だけ3つで、ほかのどの定義ともシグネチャが被っていません。


引数の型が異なっている例として、(1)、(2)を見てみましょう。(1)は(int, int)、(2)は(double, double)とシグネチャが被らず定義できています。


引数の数、型の種類が同じでも、順番が異なる例が(4)と(5)です。(4)は(int, double)、(5)は(double, int)と同じ種類の型を使っていますが、順番が違うためシグネチャは重複していません。



4.オーバーロードができない場合

先ほどの条件に当てはまらない場合、オーバーロードはできません。


よくあげられるダメな例として、戻り値の型だけを変えた場合が挙げられます。

public static int add(int x, int y) {
    int num = x + y;
    return num;
}

/*ダメな場合*/
public static double add(int x, int y) { // 戻り値の型だけ違う
    double num = x + y;
    return num;
}

先ほど条件の際に説明したように、メソッドの宣言では「シグネチャ」が異なる必要がありました。上の例では、どちらのシグネチャもadd(int x, int y)で一致してしまっており、戻り値の型が異なっても意味がありません。


オーバーロードの際にはどの部分が一致してはいけないのか、シグネチャと関連付けて覚えておきましょう。

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


コンストラクタでもオーバーロードができます。コンストラクタは、インスタンスを生成するときに必ず実行されるメソッドのことです。これを複数定義することで、引数によって行われる処理を変えられます。


以下の例を見てみましょう。

class SampleRobot {
    String color;

    public SampleRobot() {  // コンストラクタ
        System.out.println("こんにちは。");
    }

    public SampleRobot(String color) {  // 色を指定する場合のコンストラクタ
        this.color = color;
        System.out.println("こんにちは。私の色は" + color + "です。");
    }
}

public class Java_overload {
    public static void main(String[] args) {
        SampleRobot robot = new SampleRobot();
        SampleRobot blueRobot = new SampleRobot("青");
    }
}

出力:

こんにちは。
こんにちは。私の色は青です。

引数なしでインスタンスの生成をした場合は、生成と同時に「こんにちは。」とあいさつします。色名の文字列を引数にインスタンスを生成すると、インスタンス変数に色名を保存し、挨拶と同時に色名を教えてくれるようにしました。


コンストラクタでオーバーロードをする際も、メソッドと同じくシグネチャが被ってはいけないという条件があるので気を付けてください。



この記事をシェア