8_オーバーロード コンストラクタ


最初の前回の答えってのは飛ばしますがひとつだけ

Console.WriteLine( Show() )
みたいな書き方を覚えてください。
Show()はstring型をreturnするのでこのような書き方ができます
(たとえばShowがvoidだとこの書き方はできません)

メソッドのオーバーロード

では次の長いプログラムを見ましょう。
ずっとRectangleクラスばっかりで飽きてきそうですが我慢!

using System;

class Rectangle{
    int tate,yoko; //変数は連続に書くことができます。
    
    public void setTateYoko(int t,int y){   //voidです。
        tate=t;
        yoko=y;
    }

    public void setTateYoko(){    //引数がありません。
        tate=10;    //setTateYoko(10,10)とまったく同じことです
        yoko=10;    //tate=yoko=10;でもかまいません。
    }

    public void Show(){
        Console.WriteLine("tate:" + tate.ToString() +" yoko:" + yoko.ToString());
    }
}

class Test10{
    public static void Main(){
        Rectangle ra = new Rectangle();
        ra.setTateYoko();
        ra.Show();
    }
}

引数が異なると、同じ名前のメソッドが複数作れます。
ここでは引数にintを二つとったsetTateYoko、引数なしのsetTateYokoがあります。
こういう風にすることをオーバーロードといいます。
今は関係ないですがそのうち「オーバーライド」とかいう用語がでてきて
なんか名前が似ていて紛らわしいのでちゃんと覚えてください。

では次のコード

using System;

class Rectangle{
    double tate,yoko; //前と違ってdoubleにしてみました
    
    public void setTateYoko(int t,int y){   //
        tate=t;     //int型をdouble型にぶちこんでます。
        yoko=y;     
    }

    public void setTateYoko(double t,double y){//前は引数int、これはdouble
        tate=t;
        yoko=y;    //上とまったく同じ処理をしています
    }

    public void Show(){
        Console.WriteLine("tate:" + tate +" yoko:" + yoko);
    }
}

class Test10{
    public static void Main(){
        Rectangle ra = new Rectangle();
        ra.setTateYoko(10.3,100.4);//10.3と100.4はdouble
        ra.Show();
    }
}

よくみると、オーバーロードしたsetTateYokoはメソッドの中身は一緒で
引数の種類だけ違います(int,double)。今回みたいなのは二個しかないけど
引数が違うだけで同じような処理をするメソッドが大量にあると
型によるエラーも増えたりして管理面倒です。
実はいっぱい作らなくても良い方法がいくつかあるのですが今の知識だけじゃ
まだ難しくて無理なのであきらめて書いてね。

オーバーロードは引数の型や数が異なるときです。
引数が異なるってのは「名前が違う」のではなく
型が異なるということです。
つまりこれはダメ!
void setTateYoko(int x,int y)
void setTateYoko(int a,int b)
どちらも引数は違う(名前だけが)けど両方int型なので当然エラーです。

メソッドの戻り値の型だけが異なるだけではダメってのはいいでしょう。
最後にオーバーロードは便利だけど、わかりやすさ重視でかいてね。
意味不明に乱雑に同じ名前にすると何をするかわからないメソッドに
なっちまいます。
極力、同じ名前では似た処理をさせましょう。
戻り値の型を変えるのは混乱の原因になりかねないので注意!

コンストラクタ

newしたときに自動で呼ばれるメソッド。
初期設定をしたいときに使おう!

using System;

class Rectangle{
    int tate,yoko;
    
    public Rectangle(int t,int y){   //クラス名前と同じコンストラクタ
        tate=t;
        yoko=y;
    }
    public void Show(){
        Console.WriteLine("tate:" + tate +" yoko:" + yoko);
    }
}

class Test10{
    public static void Main(){
        Rectangle ra = new Rectangle(30,100);  //コンストラクタで代入
        ra.Show();
    }
}

初期化方法はもっとあります。
Rectangle ra=new Rectangle{tate=30,yoko=100};
とやると、自動的にRectangle()が呼ばれtateに30、yokoに100が入ります。
もっとも、↑のコードはtateとyokoがprivateだし
引数なしコンストラクタがないのでこの初期化方法は無理だけど。
Rectangleの後ろが( )じゃなく{ }なことだけ注意。


privateの利点

tateとyokoはprivateで、コンストラクタを利用して入れてます。
直接tate=10;yoko=20;とかやらないで
なぜ間接的な方法をとるのか?
たとえばクラスにMonth(月)とかとかage(年齢)
等のデータがあったとしましょう。
この際、Month = 13;とかMonth = -5;とかage = -136
みたいにされると厄介です。
月は1~12、年齢は正の数なのが前提だから。
想定外の値を直接入られると困る。。
「変な値」は拒否したいわけです。
そこでprivateなMonthとは別に間接的なやりかたで代入すると
たとえばこんな感じ

private Month;
public SetMonth(int month){
    if (month<1){
        Month = 1;
    }
}
これでSetMonth(-100)とかやられてもMonthに-100は入らず
1が入ります。
これは一例でもっとたくさんの利点があります。

コンストラクタのオーバーロード

コンストラクタもオーバーロード可能です。
その際、thisという単語で別のコンストラクタを呼び出せます。
これ動画でやってなかったし、自分で使うことはあまりないだろうけど
たまに使われているから
thisって書いてれば別のコンストラクタ実行可能とだけ覚えとけばいいです。

using System;
class Test{
    public Test()
    {
        Console.WriteLine("thisで呼ばれました");
    }
    public Test(string s) : this()     //←ここにthis()があります。
    {
        Console.WriteLine( s );
    }
}
class MainClass{
    static void Main(){
    Test t = new Test("まりさ");    //thisでTest()まで呼ばれてしまいます
    }
}


今回の内容とは関係ない話

たぶん多くの人は無料のVC2008を使ってると思うけど
Visual Studio 2010 βバージョンをダウンロードしてつかってみよう。
ベータバージョンなので無料です。
今すぐベータをダウンロード→WEBダウンロード
Visual Stdio 2010 Ultimateの日本語バージョンをDL
メールアドレスなどを登録すれば(しなくても可能かも)すぐ実行可能。

タグ:

+ タグ編集
  • タグ:

このサイトはreCAPTCHAによって保護されており、Googleの プライバシーポリシー利用規約 が適用されます。

最終更新:2009年11月23日 05:49