・p.169「construct02.cs」から
p.168(コンストラクタの引数とオーバーロード:再掲載+α)
・コンストラクタもメソッドの一種なので、パラメータリストを指定できる
例: public Monster(int h, int m) { hp = h; mp = m; }
・これはnewによって呼び出す時に、その値を指定する
例: Monster rimuru = new Monster(100, 500); //コンストラクタにHPとMPを渡して初期値にしてもらう
・パラメータリストを指定したコンストラクタと指定しないコンストラクタを混在できる
・また、呼び出しにおいて区別できるのであれば、パラメータリストを指定したコンストラクタを複数記述できる
・このことをオーバーロードという(※メソッド全体に対応する)
・パラメータ(引数)の数、型、順序によって区別が可能であればいくつでも指定可能
例:
public Monster() { hp = 10; mp = 20; } //コンストラクタ①
public Monster(int h) { hp = h; mp = 20; } //コンストラクタ②
public Monster(int h, int m) { hp = h; mp = m; } //コンストラクタ③
public Monster(string s) { name = s; } //コンストラクタ④
public Monster(string s, int h) { name = s; hp = h; } //コンストラクタ⑤
public Monster(int m, string s) { name = s; mp = m; } //コンストラクタ⑥
:
Monster veldra = new Monster(); //コンストラクタ①を呼ぶ
Monster slalin = new Monster(100); //コンストラクタ②を呼ぶ
Monster rimuru = new Monster(100, 500); //コンストラクタ③を呼ぶ
Monster hoimin = new Monster("ほいみん"); //コンストラクタ④を呼ぶ
Monster behoim = new Monster("べほいみん", 100); //コンストラクタ⑤を呼ぶ
Monster behoma = new Monster(500, "べほま"); //コンストラクタ⑥を呼ぶ
p.169 construct02.cs
// p.169 construct02.cs
using System;
class MyClass {
private string name; //インスタンス変数:名前
private int age; //〃:年齢
private string address; //〃:住所
public void Show() { //インスタンス変数の値を表示するメソッド
string toshi; //年齢表示用
if (age == -1) //年齢「-1」ならば不明の意味
toshi = "不明";
else //でなければ
toshi = age.ToString(); //年齢を文字列化
Console.WriteLine("氏名:{0} 住所:{1} 年齢:{2}", name, address, toshi); //全ての値をそのまま表示(年齢が-1の時のみ加工)
}
public MyClass(string str) { //コンストラクタ(氏名)
name = str; //氏名は引数から
address = "不定"; //住所は規定値
age = -1; //年齢は規定値
}
public MyClass(int x) { //コンストラクタ(年齢)
age = x; //年齢は引数から
name = "不明"; //氏名は規定値
address = "不定"; //住所は規定値
}
public MyClass(string str1, string str2, int x) { //コンストラクタ(氏名,住所,年齢)
name = str1; //氏名は引数から
address = str2; //住所も引数から
age = x; //年齢も引数から
}
}
class construct01 {
public static void Main() {
MyClass mc1 = new MyClass(18); //コンストラクタ(年齢)
MyClass mc2 = new MyClass("粂井康孝"); //コンストラクタ(氏名)
MyClass mc3 = new MyClass("田中太郎", "東京都", 32); //コンストラクタ(氏名,住所,年齢)
mc1.Show(); //1番目のインスタンスの変数値を表示
mc2.Show(); //2番目のインスタンスの変数値を表示
mc3.Show(); //3番目のインスタンスの変数値を表示
}
}
p.169(シグニチャ)
・メソッド(コンストラクタ含む)の呼び出しパターンを説明するもの ・メソッド名(コンストラクタの場合はクラス名)とパラメータリストにある引数の型の並びが、シグニチャになる 例: MyClass(string str1, string str2, int x) → MyClass(string, string, int) ・シグニチャが等しいメソッド(コンストラクタ)は同じ場には定義できない。 ・なお、戻り値型はシグニチャに含まれないので、メソッドの場合に注意。
p.170(引数のあるコンストラクタと引数のないコンストラクタ)
・クラスにコンストラクタをまったく記述しないと「クラス名(){}」という中身がなく引数のないコンストラクタが自動作成される
・引数のあるコンストラクタを1つでも記述すると、↑の働きは起きないので、必要ならば自前で作成すること
・呼び出し時に引数をまったく指定しない時に、呼び出されるコンストラクタをデフォルトコンストラクタという。
・基本的には「引数のないコンストラクタ」=「デフォルトコンストラクタ」だが、後述の可変長引数(p.201)などを用いると、
引数指定のあるデフォルトコンストラクタも記述可能。
p.171 デストラクタ
・プログラム内で生成されたオブジェクトは、基本的に完了時に消去される
・C#システムがメモリの残量を検知して、利用されないオブジェクトを削除する機能があり、これをガーベージ・コレクションともいう。
ただし、その実行を依頼したり、実行をプログラムから制御することは不可。
・そして「オブジェクトの生成時に呼ばれる」コンストラクタと逆に「オブジェクトの消去時に呼ばれる」デストラクタがあり、
実行は制御できないが、確実に実行できる、
※ よって、コンストラクタが行ったことの後始末に用いることもある(例:DB切断)
・複数のオブジェクトが破棄された場合、デストラクタの実行順序は不定。
・書式: ~クラス名() { 処理内容; }
・コンストラクタと同様に戻り値はなく、パラメータリストもない(よって、オーバーロードもない)
p.172 destruct01.cs
//p.172 destruct01.cs
using System;
class DestructTest {
int x; //インスタンス変数
// デストラクタ
~DestructTest() {
Console.WriteLine("デストラクタが呼ばれました");
Console.WriteLine("xは{0}です", x);
}
// 引数付きコンストラクタ
public DestructTest(int n) {
Console.WriteLine("コンストラクタが呼ばれました");
x = n;
Console.WriteLine("xに{0}を代入しました", n);
}
}
class destruct {
public static void Main() {
DestructTest dt1 = new DestructTest(1);
Console.WriteLine("dt1生成");
DestructTest dt2 = new DestructTest(2);
Console.WriteLine("dt2生成");
DestructTest dt3 = new DestructTest(3);
Console.WriteLine("dt3生成");
}
}
アレンジ演習:p.172 destruct01.cs
・string型のインスタンス変数を定義して、コンソールから入力し、オブジェクト生成時にコンストラクタ(文字列)から値を得よう ・デストラクタではその文字列を表示しよう ・なお、3つのオブジェクトはどれも同じ参照変数dt1を用いること(こうしてもデストラクタは3回動作する)
作成例
//アレンジp.172 destruct01.cs
using System;
class DestructTest {
string x; //インスタンス変数
// デストラクタ
~DestructTest() {
Console.WriteLine(x);
}
// 引数付きコンストラクタ
public DestructTest(string n) {
x = n;
}
}
class destruct {
public static void Main() {
Console.Write("dt1の断末魔:");
DestructTest dt1 = new DestructTest(Console.ReadLine());
Console.Write("dt2の断末魔:");
dt1 = new DestructTest(Console.ReadLine()); //この時点で1つめのオブジェクトは利用不能になるが存続する
Console.Write("dt3の断末魔:");
dt1 = new DestructTest(Console.ReadLine()); //この時点で2つめのオブジェクトも利用不能になるが存続する
} //終了時点で3つ分のデストラクタが動作する
}