C++/C#/Java オーバーロードを使ったやって欲しくない実装
はじめに
今回は、オーバーロードを使ったあんまりやって欲しくない実装方法を説明します。
C#で書きますが、C++, Javaなどオブジェクト指向全般で同じです。
オーバーロードの説明
オブジェクト指向言語にはオーバーロードと言う文法があります。
だいたいこんな説明ですね。
「クラス内に同じ名前のメソッドを複数作ることができる」
ただし、
「引数の型や数が異ならないとオーバーロードとして定義できない」
「あくまで引数の型や数なので、戻り値が違う場合もオーバーロードとして定義できない」
オーバーロードの例
オーバーロードの用法として、
こんな感じのソースがあったら、
class Program
{
static void Main()
{
Student student = new Student();
student.SetID(1001);
student.SetScore(80.5);
student.Show();
}
}
class Student
{
private int ID;
private double Score;
public void SetID(int id) { ID = id; }
public void SetScore(double score) { Score = score; }
public void Show()
{
System.Console.WriteLine(string.Format("ID:{0} Score:{1}", ID, Score));
}
}
結果:”ID:1001 Score:80.5″
SetIDとSetScoreはどちらも値を設定するので、
似たような処理は同じ名前にしてオーバーロードすると見やすくなります。
class Program
{
static void Main()
{
Student student = new Student();
student.Set(1001);
student.Set(80.5);
student.Show();
}
}
class Student
{
private int ID;
private double Score;
public void Set(int id) { ID = id; }
public void Set(double score) { Score = score; }
public void Show()
{
System.Console.WriteLine(string.Format("ID:{0} Score:{1}", ID, Score));
}
}
みたいな説明があると思います。
オーバーロードの動きがよくわかりました!!
オーバーロードを知るにあたっては上のような例で特に問題ないです。
同じ関数名でも引数が違えば振る舞いが変わる。
これがよく理解できます。
intならIDで、doubleならScoreね…
あまり良くないと思うところ
持論ですが、関数名は直観的に使えた方がいいと思っています。
引数が違えば振る舞いが変わるので、関数名が同じでいいはずがありません。
私がコードレビューで見たらたぶんNGにしてしまいます。
ダメだと思うところは、
- 同じ名前のメソッドが別々の2種類のメンバに値を設定している
- どっちがどっちに、設定するか直感でわからない
です。
見やすくしたと言っても、わかりづらくてはダメです…
結論
最初に出した例の方が何(ID or Score)に何(設定)をしたいと言うのがよくわかるので、
無理にオーバーロードを使わない方がいいです。
じゃーオーバーロードいらなくね?
いえいえ、オーバーロードはやさしさと力強さを兼ね揃えています。
次回は、オーバーロードを使うべき3つのポイントを説明します。