C++/C#/Java オーバーロードを使ったやって欲しくない実装

rpg3

はじめに

今回は、オーバーロードを使ったあんまりやって欲しくない実装方法を説明します。
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ね…

あまり良くないと思うところ

overload_1-1

持論ですが、関数名は直観的に使えた方がいいと思っています。
引数が違えば振る舞いが変わるので、関数名が同じでいいはずがありません。
私がコードレビューで見たらたぶんNGにしてしまいます。

ダメだと思うところは、

  1. 同じ名前のメソッドが別々の2種類のメンバに値を設定している
  2. どっちがどっちに、設定するか直感でわからない

です。

見やすくしたと言っても、わかりづらくてはダメです…

overload_1-2

結論

最初に出した例の方が何(ID or Score)に何(設定)をしたいと言うのがよくわかるので、
無理にオーバーロードを使わない方がいいです。

じゃーオーバーロードいらなくね?
いえいえ、オーバーロードはやさしさと力強さを兼ね揃えています。

次回は、オーバーロードを使うべき3つのポイントを説明します。

 

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です