講義メモ 後半

p.201 引数が可変個のメソッド

・メソッドの引数にparamsキーワードと配列を指定することで、引数が可変個のメソッドになる
・よって、同型の引数をいくつでも指定できる1メソッドが記述できる
・書式: アクセス修飾子 戻り値型 メソッド名(params 配列型[] 仮引数) {…}
・メソッド内部では仮引数を配列として、各引数はその要素になる
・よって、引数の数は、仮引数.Lengthで得ると良い
・引数が0個でもかまわないが、要素数0の配列になるので、要素を使用すると異常終了する

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

・「if(animal1.Length == 0)」は不用なので消そう
・その後ろのfor文はforeachで書き換えよう
・Mainにおいて、引数が1個の場合、2個の場合を加えよう
・また、引数をint型にしたメソッドでオーバーロードできるが条件があることを確認しよう
 ⇒ 引数が0個である呼び出しをすると、両方にマッチしてしまうので、エラーになる

作成例

//p.201 params01.cs
using System;
class MyClass {
    public void show(params string[] animal) { //string型の可変個引数のメソッド
        foreach (var w in animal) { //全引数について繰返す
            Console.WriteLine("{0}さんがいます", w);
        }
    }
    public void show(params int[] animal) { //int型の可変個引数のメソッド
        foreach (var w in animal) { //全引数について繰返す
            Console.WriteLine("{0}です", w);
        }
    }
}
class params01
{
    public static void Main()
    {
        MyClass mc = new MyClass();
        //mc.show(); //showメソッドをオーバーロードにしたので区別不可でエラーになる
        mc.show("ぱんだ");
        mc.show("いぬ", "ねこ");
        mc.show("きりん", "ぞう", "かば");
        mc.show(100);
        mc.show(200, 300);
    }
}

ミニ演習:mini202.cs

・実数の可変個引数を受け取って、平均値を返す double ave(params double[]) を作成し、動作を確認しよう

作成例

//ミニ演習:mini202.cs
using System;
class MyClass {
    public double ave(params double[] val) { //double型の可変個引数のメソッド
        double sum = 0.0; //合計
        foreach (var w in val) { //全引数について繰返す
            sum += w; //合計に足し込む
        }
        return sum / val.Length; //平均値を返す
    }
}
class params01 {
    public static void Main() {
        MyClass mc = new MyClass();
        Console.WriteLine(" = {0}",              mc.ave());
        Console.WriteLine("1.1 = {0}",           mc.ave(1.1));
        Console.WriteLine("1.1, 2.2 = {0}",      mc.ave(1.1, 2.2));
        Console.WriteLine("1.1, 2.2, 3.3 = {0}", mc.ave(1.1, 2.2, 3.3));
    }
}

p.202 静的メンバ

・通常、クラスの各メンバはインスタンスに所属する
 例:Slimeクラスにhpを定義すると、Slimeクラスのインスタンスslalinに所属し、slalin.hpになる
・しかし、インスタンスに所属する必要がないような=クラスに所属するメンバも記述できる
・それが静的メンバで、staticを前置して示す
 例:Slimeクラスに「生成したスライム数」を持たせる場合、インスタンスには所属しないので、クラスで持つ方が良い
・また、インスタンス変数を全く用いないメソッドもクラスで持つ方が良く、これを静的メソッドという
・静的メンバはクラスに所属するので「クラス名.」を前に付けて実行する
・よって、静的メンバはインスタンスの生成をしなくても利用できる
・なお、Console.WriteLineは、Consoleクラスの静的メソッドなので「Console.」を前につけている
・また、Mathクラスのメンバの大半は静的メンバ(例:Math.PI)
・近い理由で、Mainメソッドも静的メソッドである必要があるので「static」を前置する
・逆に言えば、静的メンバはインスタンスごとにはならない特殊なものであり、オブジェクト指向のメリットを生かせないので乱用は避けること。
※ つまり、設計図に直接データを書き込んでいるようなイメージ

アレンジ演習:p.203 static01.cs

・変数xにMyClassのインスタンスの生成数を格納するようにして、動作を確認しよう
・生成はデフォルトコンストラクタでのみ行うとする

作成例

//p.203 static01.cs
using System;
class MyClass {
    public static int x; //静的データメンバ(インスタンス数)
    public static void showX() { //静的メソッド
        Console.WriteLine("x = {0}", x);
    }
    public MyClass() { //【追加】コンストラクタ
        x++; //静的データメンバをインクリメント
    }
}
class static01 {
    public static void Main() {
        MyClass.x = 0; //静的データメンバなので直接アクセスできる
        MyClass.showX(); //静的メソッドなので直接呼び出せる
        MyClass m1 = new MyClass(); //【追加】コンストラクタが呼ばれる
        MyClass.showX(); //静的メソッドなので直接呼び出せる
    }
}

作成例(発展形)

//p.203 static01.cs
using System;
class MyClass {
    public static int x; //静的データメンバ(インスタンス数)
    public static void showX() { //静的メソッド
        Console.WriteLine("x = {0}", x);
    }
    public int n; //【追加】自分は何番目かを示すインスタンス変数
    public MyClass() { //【追加】コンストラクタ
        x++; //静的データメンバをインクリメント
        n = x; //自分は何番目か
    }
    public void showN() { //【追加】インスタンスメソッド
        Console.WriteLine("ボクは{0}番目です", n);
    }
}
class static01 {
    public static void Main() {
        MyClass.x = 0; //静的データメンバなので直接アクセスできる
        MyClass.showX(); //静的メソッドなので直接呼び出せる
        MyClass m1 = new MyClass(); //コンストラクタが呼ばれる
        m1.showN(); //【追加】インスタンスメソッドで何番目かを表示
        MyClass m2 = new MyClass(); //コンストラクタが呼ばれる
        m2.showN(); //【追加】インスタンスメソッドで何番目かを表示
        MyClass m3 = new MyClass(); //コンストラクタが呼ばれる
        m3.showN(); //【追加】インスタンスメソッドで何番目かを表示
    }
}

提出:アレンジ演習:p.203 static01.cs

コメントを残す

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