補足記事

メソッドのオーバーロードって何?

同じ名前のメソッドを、引数を渡して呼んだり、渡さずに呼んだりしたい。そんなときに役に立つのがオーバーロードです。挨拶をするhelloメソッドを例に、使い方と約束事を見てみましょう。

オーバーロードとは?

 引数を受け取って処理するメソッドを定義すると、そのメソッドを呼ぶ時は、受け取れる型と個数に合った引数を渡す必要があります。けど、場合によっては同じ名前のメソッドに、いろんな引数を渡したい時もあると思います。

 例えば、こんなメソッドを作ったとします。以下のコードは、Hello.javaのHelloクラス内に書くメソッドの部分です。

Hello.java

public static void hello(String name) {
    System.out.print(name + "さん、こんにちは");
}

 このメソッドは引数に文字列を渡して呼ぶと、「○○さん、こんにちは」と画面に出力されるメソッドです。mainメソッドの中で、

Hello.java

hello("田中");

 とやると、次のように出力されますね。

実行結果
田中さん、こんにちは

 このメソッドを呼ぶ時は誰かの名前を渡す必要があります(もちろん名前じゃなくても文字列なら何でもいいんですが……)。

 もし、単純に相手を指定せずに「こんにちは」とだけ出力させたかったら、どうしたらいいでしょうか? 相手を指定しないんだから、引数に何も渡さずに呼んでみたらどうでしょう?

Hello.java

hello();

 これだと、コンパイルエラーになります。今あるのはString型の引数を一つ受け取るhelloメソッドだけなので、引数を省略することはできません。

 こういう場合に役に立つのがオーバーロードです。こうやります。

Hello.java

public static void hello(String name) {
    System.out.print(name + "さん、こんにちは");
}

public static void hello() {
    System.out.print("こんにちは");
}

 同じ名前のメソッドで、引数を受け取らないものをもう一つ定義するんです。こうしておくことで、引数を渡さずに呼んだ場合は、下側のhelloメソッドが呼び出されます。

 このように、同じメソッド名で引数の型や個数などが異なるものを定義することを、そのメソッドをオーバーロードすると言います。

 全体のコードで確認してみましょう。二つの出力を見やすくするため、間でSystem.out.println()を呼んで改行しています。

Hello.java

public class Hello {
    public static void main(String[] args) {
        hello("田中");
        System.out.println();
        hello();
    }

    public static void hello(String name) {
        System.out.print(name + "さん、こんにちは");
    }

    public static void hello() {
        System.out.print("こんにちは");
    }
}
実行結果
田中さん、こんにちは
こんにちは
呼び出し呼ばれるメソッド
hello("田中")hello(String name)
hello()hello()

オーバーロードの約束事

 同じ名前のメソッドを複数定義しても、どれを呼ぶのか区別できれば困りません。逆に区別できない定義は、コンパイルエラーになります。オーバーロードとして扱ってもらうには、守るべき約束事があります。

 その約束は、引数の型の並びが全く同じものはダメ、ということです。引数の型・個数・型の順番のいずれかを変える必要があります。

 例えば、次の二つを同じクラスに定義することはできません。

Hello.java

public static void hello(String man) {
    System.out.print(man + "くん、ちわっす");
}

public static void hello(String woman) {
    System.out.print(woman + "さん、こんにちは");
}

 こんなのは仮引数の名前が違うだけなので、オーバーロードとは見なしてくれません。もしhello("田中")と呼ばれたら、どっちのメソッドを呼べばいいか判断のしようがないですから。どちらも「String型を一つ受け取るhello」という同じ定義になってしまいます。

 逆に、次のような違いがあればオーバーロードできます。表では、メソッド名と引数の部分だけを抜き出しています。

変えるところ定義の組み合わせ
引数の個数hello() と hello(String name)
引数の型hello(String name) と hello(int number)
引数の型の順番hello(String name, int number) と hello(int number, String name)

 戻り値の型、アクセス修飾子、staticの有無だけを変えても、オーバーロードにはなりません。引数の型の並びが異なっていれば、それらが同じでも違っていてもオーバーロードできます。ただし、それぞれのメソッドの宣言や呼び出しは、通常のJavaのルールにも従う必要があります。

 まずは、「同じ名前でも、引数の型の並びが違えば、別のメソッドとして定義できる」という点を押さえておけばOKです!

名前の似ているオーバーライドは、継承したメソッドの処理をサブクラスで定義し直すことです。オーバーロードとは別の仕組みなので、混同しないようにしましょう。

全講座の目次へ戻る

質問・コメント

読み込み中

この記事についての質問や、学習して気づいたことをお寄せください。

コメントを書く

投稿フォームを準備しています。

コメントと一緒に公開される名前です。
3,000文字以内。パスワードなどの個人情報は書き込まないでください。

コメントは送信後すぐに公開されます。

この記事のコメント

旧サイトに寄せられたコメントも当時の投稿内容のまま掲載しています。現在の記事では変更している内容や、旧環境についてのやり取りも含まれます。

コメントを読み込んでいます。