日々常々

ふつうのプログラマがあたりまえにしたいこと。

オーバーロードの誤用

正しい使い方のされない道具は害悪にしかなりません。
鋏は正しく使えば紙や布をさくさくと切る事が出来るけど、変に傾けたりすると全くきれなかったり、普通の鋏で鉄パイプやらを切ろうとしても文字通り歯が立たない、さらに人に向けたりすると危険です。道具にはそれぞれ決まった使い方があって、その分野では適した働きをするけれども、違う分野では役立たずになったり邪魔になったりします。

さてJavaにはオーバーロードと呼ばれる記述方法があります。「引数の異なるメソッドは同じ名前でも別物として扱われる」というだけのものです。コードをあげるならこんな感じ。

public void hoge() {
  //省略
}
public String hoge(int i) {
  //省略
}
private int hoge(boolean b) {
  //省略
}

この場合、hogeメソッドと言っても3つもありますし、引数も戻り型も違っています。一部の方は「どれが実行されるかわからないのでコードが追い辛くなる」だとか妙ちくりんな理由を付けてオーバーロードを嫌っていたりします。
もっとも嫌う理由も判らないでもありません。全く関連のない機能なのに引数が違うだけで同名のメソッドを実装しているシステムもあります。たとえばこんな感じ。

public long calc(int a, int b) {
  return a + b;
}
public long calc(int a, long b) {
  return a - b;
}
public long calc(long a, long b) {
  return a * b;
}

両方intだったら足し算の結果を、両方longだったら掛け算の結果を、第一引数がintで第二引数がlongだったら引き算のけ結果を返します。訳がわかりません。流石にこんなものを実際に見たことはありませんが、近いものなら何度か目の当たりにしています。*1メソッド名を考えるのが面倒だったのでしょうか。それとも引数さえ違えばメソッド名は同じに出来ると解釈をしてしまったのでしょうか。もしオーバーロードとはこういうものだと認識してしまえば、使いたくなくなるでしょうし、見たくもなくなると思います。こういうのが誤用です。
オーバーロードは、オーバーロードを記述する人がメソッド名を考える手間を省くためのものではありません。オーバーロードされたメソッドを使いたい人が、引数の型を意識せずに使えるようにするためのものです。そしてメソッド名は、そのメソッドが何をするものなのかを表すべきです。つまり、どの引数で実行されても、同じ結果となるものに対して、オーバーロードは実装されるべきです。
オーバーロードは、そのクラスを実装する人には単なる手間であって、使用する人を楽にしてくれるものです。例えば引数の型を変換せずそのまま使用できたり、デフォルト値を使用したい引数の省略を許容してくれます。こうした形で実装されたメソッドは、使用する側にとってはとても便利です。例は、java.ioだとかjava.langだとかに溢れていますので、特に挙げません。

*1:実際の開発現場で。泣きそうになりました。