こんにちは、かつコーチです。
「引数の数や型が違うだけの似たようなメソッドを、いちいち別名で作るのは面倒」と感じたことはありませんか。
Javaにはオーバーロード(同じ名前で引数の型・数・順序が異なる複数のメソッドを定義できる仕組み)という機能があります。
この記事では、オーバーロードの使い方と、初心者がつまずきやすいポイントを解説します。
メソッドのオーバーロードとは
同じ名前で引数違いのメソッドを定義する仕組み
オーバーロードとは、1つのクラスの中に同じメソッド名で、引数の型・数・順序が異なるメソッドを複数定義できる仕組みです。
呼び出し時に渡す引数の内容によって、Javaのコンパイラがどのメソッドを実行するかを自動的に判断してくれます。
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
public int add(int a, int b, int c) {
return a + b + c;
}
}
上記のaddは名前が同じでも、引数の型や数が異なるため、それぞれ別のメソッドとして扱われます。
なぜオーバーロードが必要なのか
オーバーロードがないと、「整数を足すadd」「小数を足すaddDouble」「3つ足すaddThree」のように、似た処理ごとに別々の名前を考える必要があります。
これでは呼び出す側も「今回はどの名前を使えばいいのか」を毎回調べる手間が発生します。
オーバーロードを使えば、利用者は「add」という名前だけ覚えておけばよく、渡す引数に応じて適切な処理が自動的に選ばれます。
Javaの標準ライブラリでも、System.out.println()はint、String、doubleなど様々な型に対応したオーバーロードが用意されています。
基本の書き方・実装手順
手順1:引数の型を変えてオーバーロードする
public class MessagePrinter {
public void print(String message) {
System.out.println("文字列: " + message);
}
public void print(int number) {
System.out.println("数値: " + number);
}
public static void main(String[] args) {
MessagePrinter printer = new MessagePrinter();
printer.print("こんにちは"); // 文字列: こんにちは
printer.print(100); // 数値: 100
}
}
呼び出し時に渡した値の型を見て、コンパイラが適切なprintメソッドを選んでくれます。
手順2:引数の数を変えてオーバーロードする
public class AreaCalculator {
// 正方形の面積
public int calculateArea(int side) {
return side * side;
}
// 長方形の面積
public int calculateArea(int width, int height) {
return width * height;
}
public static void main(String[] args) {
AreaCalculator calc = new AreaCalculator();
System.out.println(calc.calculateArea(5)); // 25
System.out.println(calc.calculateArea(5, 3)); // 15
}
}
引数の数が異なれば、型が同じでもオーバーロードとして成立します。
つまずきやすい設定・注意点
オーバーロードとして認められるのは、以下のいずれかが異なる場合だけです。
- 引数の型
- 引数の数
- 引数の順序(型の組み合わせが異なる場合)
戻り値の型だけが違うメソッドは、オーバーロードとして認められません。
よくあるつまずきポイント・エラー対処
戻り値の型だけ変えて定義しようとする
初心者が最初につまずきやすいのが、「戻り値の型だけ変えれば別のメソッドとして扱われる」という誤解です。
❌Before
public class Calculator {
public int add(int a, int b) {
return a + b;
}
// 戻り値の型だけ変えてもオーバーロードにはならない
public double add(int a, int b) {
return a + b;
}
}
このコードをコンパイルすると、次のエラーが出ます。
error: method add(int,int) is already defined in class Calculator
私も学習し始めの頃、「int版とdouble版で結果を使い分けたい」と考えてこのミスをしました。
エラーメッセージの「already defined(既に定義されている)」が、原因を教えてくれています。
✅After
public class Calculator {
public int add(int a, int b) {
return a + b;
}
// 引数の型を変えることでオーバーロードとして成立させる
public double add(double a, double b) {
return a + b;
}
}
戻り値だけでなく、引数の型・数・順序のいずれかを変える必要があります。
あいまいな呼び出しでコンパイルエラーになる
intとlongの両方を受け取るオーバーロードがある場合、リテラルの書き方によっては、どちらを呼びたいのか特定できずエラーになることがあります。
public void show(long value) { System.out.println("long: " + value); }
public void show(double value) { System.out.println("double: " + value); }
show(10); // intの10はlongに自動変換されるためlong版が呼ばれる(あいまいではない)
このケース自体は問題なく動きますが、オーバーロードの組み合わせが増えるほど「どのメソッドが呼ばれるか」が直感的に分かりにくくなります。
迷ったときは、いったんIDEの補完機能で呼び出し候補を確認する習慣をつけましょう。
応用・一歩先の使い方
可変長引数との使い分け
引数の数がその都度変わる場合、オーバーロードでadd(int a, int b)、add(int a, int b, int c)と個別に用意するより、次の記事で紹介する可変長引数(varargs)を使うほうがシンプルになる場合があります。
「引数のパターンが数種類に決まっている」ならオーバーロード、「引数の数が不定」なら可変長引数、と使い分けるのが目安です。
まとめ
この記事のポイント
- オーバーロードは、同じメソッド名で引数の型・数・順序が異なる複数のメソッドを定義できる仕組み
- 戻り値の型だけを変えてもオーバーロードとしては認められず、コンパイルエラーになる
- 呼び出し時に渡した引数の内容から、コンパイラが実行するメソッドを自動判断する
- 引数の数が不定な場合は、可変長引数との使い分けを検討する
次に読むべき記事
- 引数の数が不定な場合の書き方は、可変長引数(varargs)の使い方の記事で解説します
- メソッドの基本構文をまだ確認していない方は、メソッドの定義と引数の基本の記事もあわせてご覧ください
タグ: Java, 中級者向け, 基本文法