メソッドのオーバーロード
同じことをするのに、名前を 3 つ覚えたくない
画面に何かを出すとき、私たちが覚えている名前は System.out.println の 1 つだけです。ところが渡しているものは、あるときは文字列、あるときは整数、あるときは小数とばらばらです。それでも printText printInt printDouble と呼び分けた覚えはないはずです。
自分でメソッドを書き始めると、この便利さが当たり前ではないと気づきます。たとえば値を括弧で囲んで表示用の文字列にするメソッドを作ると、扱う型ごとに名前を変えたくなります。
Java
public static String tagText(String value) { ... }
public static String tagNumber(int value) { ... }呼ぶたびに「これは数値だから tagNumber だったか」と考えることになり、覚える名前だけが増えていきます。
引数の型か個数が違えば、同じ名前が使える
Java では、同じクラスの中に同じ名前のメソッドを何本も置けます。条件は 1 つだけで、引数の型か個数が違うことです。これをオーバーロードと呼びます。
Java
public class Formatter {
public static String tag(String value) {
return "[" + value + "]";
}
public static String tag(int value) {
return "[" + value + "点]";
}
public static String tag(String value, String mark) {
return mark + value + mark;
}
}3 本とも名前は tag ですが、Java から見れば別のメソッドです。呼ぶ側は tag("春") tag(80) tag("春", "*") と自然に書くだけで、どれを実行するかは渡した引数を見てコンパイラが選んでくれます。System.out.println も Math.max も、中身はこの仕組みです。使う人が名前を 1 つ覚えれば済むように、ライブラリの側が何本も用意してくれています。
名前と引数が同じなら、それは同じメソッド
見分けに使われるのは、名前と、引数の型と個数と並び順だけです。戻り値の型は含まれません。
Java
public static String tag(int value) { ... }
public static int tag(int value) { ... } // 通らないこの 2 本は Java から見るとどちらも tag(int) なので、already defined と言われて止まります。tag(80) と書いた時点では、結果を何で受け取るかがまだ決まっていません。戻り値では選びようがないのです。
同じ理由で、引数の名前だけを value から text に変えても別物にはなりません。
別のクラスに同じ名前のメソッドがあっても、それはオーバーロードではありません。たまたま名前が同じだけの、無関係なメソッドです。
やってみよう
今回は Solution クラスに add2(int a, int b) を書きます。テストはこのシグネチャに対して走るので、クラス名もメソッド名も引数の型と個数も変えないでください。
通ったら実験してみましょう。同じクラスに引数が 1 つだけの同名メソッドを足しても、テストは通ったままのはずです。次に、引数はそのままで戻り値の型だけ違うものを足してみてください。どこで止まるかを自分の目で確かめると、シグネチャに何が含まれているかが体に残ります。
要件
- Solution クラスに
public static int add2(int a, int b)を実装すること - メソッドの中身は
a + bを計算し、結果を int でreturnすること - クラス名・メソッド名・引数の型と個数を変えないこと (テストは add2(int, int) のシグネチャに対して走る)
入出力例
add2(2, 3) → 5
add2(-1, 1) → 0
add2(10, 20) → 30
add2(0, 0) → 0
add2(-5, -7) → -12
add2(100, 250) → 350