講義メモ 後半

p.205 静的メンバとインスタンスメンバの混在

・1つのクラスに静的メンバとインスタンスメンバを混在させることが可能
・ただし、静的メソッドはインスタンスメンバにアクセスできないので、下記は不可
 ① 静的メソッドの中でインスタンス変数を用いる
 ② 静的メソッドからインスタンスメソッドを呼び出す
・また、静的メソッドでは自オブジェクトを示すthisは使えない

p.205 static03.cs

//p.205 static03.cs
using System;
class Cat {
    static int NoOfTail; //尾の数は猫共通なので猫クラスに所属する静的変数
    string Name; //名前は猫共通ではなくオブジェクトに所属するインスタンス変数
    public void SetName(string strName) { //インスタンス変数を扱うインスタンスメソッド
        Name = strName; //インスタンス変数に代入
    }
    public void ShowCat() { //インスタンス変数も扱うインスタンスメソッド
        if (Name == null) { //インスタンス変数を用いる
            Console.WriteLine("名前が設定されていません");
            return;
        }
        Console.WriteLine("猫の名前は{0}で尾の数は{1}本です",
            Name, NoOfTail); //インスタンス変数と静的変数を扱うことが可能
    }
    public static void setCatTail(int no) { //静的変数のみを扱う静的メソッド
        //ここでインスタンスフィールドにアクセス不可
        //Name = "マイケル";
        NoOfTail = no; //静的変数に代入
    }
}
class static03 {
    public static void Main() {
        Cat.setCatTail(1); //静的メソッドを用いて猫共通の尾の数を設定
        Cat mycat = new Cat(); //インスタンス①を生成
        Cat yourcat = new Cat(); //インスタンス②を生成
        mycat.ShowCat(); //①のインスタンスメソッドを呼ぶ
        mycat.SetName("マイケル"); //同上
        yourcat.SetName("パトリシア"); //②のインスタンスメソッドを呼ぶ
        mycat.ShowCat(); //①のインスタンスメソッドを呼ぶ
        yourcat.ShowCat(); //②のインスタンスメソッドを呼ぶ
    }
}

p.207 プロパティ

・データメンバへの値の設定や、データメンバからの値の読み出しは、データメンバをpublicにすれば自由にできるが、
 不適切な値の設定や、想定されていない読み出しがされることが避けられない。
・そこで、データメンバをprivate等に設定し、値の設定や値の読み出しは、メソッド経由にすることをカプセル化(p.4、p.166)という
・この場合に用いる値の設定や値の読み出し用のメソッドをアクセッサともいう
・アクセッサの記述に適した特別なメソッドの記述法がプロパティで、引数を持たず変数と同様に利用できる
・定義書式: public 型 プロパティ名 { get {…; return 値や式;} set {…;} }
 ※ 型は扱いたいデータメンバに合わせる
 ※ getの中においてデータメンバの値を返す
 ※ setの中では外部から与えられる値をvalueキーワードで得ることができ、通常、これをデータメンバに代入
・基本的な定義書式: public 型 プロパティ名 { get {return 変数名;} set {変数名 = value;} }
・代入式の左辺にプロパティを指定すると、setの内容が実行される。例:プロパティ名 = 値;
・代入式の左辺以外にプロパティを指定すると、getの内容が実行される。例:Console.Write(プロパティ名);
・getとsetのどちらかを省略可能で、setを省略することで外部からの値の設定を禁止(読み込み専用に)できる
・プロパティで不適切な値の設定を防ぐには、setにおいて値のチェックを行えば良い
 例: public double BH { set { if(value > 0) Height = value; } } //身長は正の数のみ設定可能

p.208 prop01.cs

//p.208 prop01.cs
using System;
class MyClass {
    double bl; //非公開のインスタンス変数
    public double blprop { //インスタンス変数bl用のプロパティ
        get { return bl; } //値の読み出し(「return 」)
        set { bl = value; } //値の設定で、「blprop = 値や式」とすると呼び出される
    }
}
class prop01 {
    public static void Main() {
        MyClass mc = new MyClass();
        mc.blprop = 165.2; //プロパティのsetを呼び出す
        Console.WriteLine("bl = {0}", mc.blprop); //プロパティのgetを呼び出す
    }
}

p.209 prop02.cs

//p.209 prop02.cs
using System;
class BMI {
    double bw, bl; //非公開のインスタンス変数で体重、身長
    public double blprop { //身長用のプロパティ
        get { return bl; }
        set {
            if (value <= 0) { //代入値が0以下?
                Console.WriteLine("身長に0または負の値は設定できません");
                return; //終わって戻る
            }
            bl = value; //身長に代入値を代入
        }
    }
    public double bwprop { //体重のプロパティ
        get { return bw;  }
        set {
            if (value <= 0) { //代入値が0以下?
                Console.WriteLine("体重に0または負の値は設定できません");
                return; //終わって戻る
            }
            bw = value; //体重に代入値を代入
        }
    }
    public double CalcBMI() {
        if (bl == 0.0 || bw == 0.0) {
            Console.WriteLine("データがセットされていません");
            return 0.0;
        }
        return bw / Math.Pow(bl, 2.0); //BMI値を計算して戻す
    }
}
class prop02 {
    public static void Main() {
        BMI mybmi = new BMI();
        double bl, bw; //身長、体重
        do { //繰返し開始
            Console.Write("身長(m)--- ");
            string strBl = Console.ReadLine();
            bl = double.Parse(strBl);
            mybmi.blprop = bl;
        } while (bl <= 0.0); //身長に0以下の値が入力されている間繰返す=抜けない
        do { //繰返し開始
            Console.Write("体重(kg)--- ");
            string strBw = Console.ReadLine();
            bw = double.Parse(strBw);
            mybmi.bwprop = bw;
        } while (bw <= 0.0); //体重に0以下の値が入力されている間繰返す=抜けない
        Console.WriteLine("bl = {0}, bw = {1}", 
            mybmi.blprop, mybmi.bwprop); //プロパティで身長と体重を得て表示
        Console.WriteLine("BMI = {0:#.#}", mybmi.CalcBMI());
    }
}

p.211(静的プロパティ)

・静的データメンバのみを扱うプロパティは静的プロパティにすると良い
・すると「クラス名.プロパティ名」で扱うことが可能になる
・ただし、静的プロパティはインスタンスメンバにアクセスできないので、下記は不可
 ① 静的プロパティの中でインスタンス変数を用いる
 ② 静的プロパティからインスタンスメソッドを呼び出す

p.211 prop03.cs

//p.211 prop03.cs
using System;
class Test {
    static int x; //静的データメンバ
    public static int myprop { //静的プロパティ
        get { return x; }
        set { x = value; }
    }
}
class prop03 {
    public static void Main() {
        Test.myprop = 10; //静的プロパティ(クラス名.プロパティ名)を用いて値を代入
        Console.WriteLine("Test.myprop = {0}", Test.myprop); //静的プロパティを用いて値を得る
    }
}

p.212 インデクサ

・主にデータメンバである配列等をプロパティと同様に扱う仕掛けがインデクサ
・プロパティとは異なり、インデクサには名前がなく「インスタンスの参照変数[添字]」の形式で、配列の要素を扱える
・定義書式: public 型 this[インデックス型 インデックス] { get {…; return 値や式;} set {…;} }
 ※ 型は扱いたい配列等に合わせる
 ※ getの中において配列等の要素[インデックス]の値を返す
 ※ setの中では外部から与えられる値をvalueキーワードで得ることができ、通常、これを要素[インデックス]に代入
・基本的な定義書式: public 型 this[int i] { get {return 配列名[i];} set {配列名[i] = value;} }
・代入式の左辺に参照変数[添字]を指定すると、setの内容が実行される。例:参照変数[0] = 値;
・代入式の左辺以外に参照変数[添字]を指定すると、getの内容が実行される。例:Console.Write(参照変数[0]);

提出:アレンジ演習:p.201 params01.cs

コメントを残す

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