C++/CLIをつつく16-抽象型。時には曖昧に。
実は前回のプログラムには凄くおかしなところがあります。
さて、それはどの点でしょうか?
チッチッチッチチッチッチッチチッチッチッチチッチッチッチチッチッチッチチッチッチッチ
時間切れピヨ。さて答えを発表するぞ。
答えは・・・Animalクラスのインスタンスを作れる事ピヨ。
動物って、凄く曖昧な表現だよね。その曖昧なもののインスタンス化を認めちゃうとおかしなプログラムが出来上がる。 この短い例だとわかりにくいかもしれないけど、動物園の管理システムを作っている事を想像してごらん。 動物に名前と年齢をつけるって事は、動物園の人達が「何の動物か分からない無いけど飼育している」状態なんだ。 おかしいよね。それじゃ未確認飛行物体ならぬ未確認生命体だよ。まぁ、実際存在したら凄く魅力的な動物園だけどね。 それじゃあ普通はプログラムのエーラーと捉えるよね? ということで、Animalクラスのインスタンス化を禁止するコードを実装するピヨ。 とぉー
//宣言に注目
public ref class Animal abstract
{
private:
Int32 m_age;
String^ m_name;
Animal(){}
public:
property Int32 Age {
Int32 get() { return this->m_age; }
void set( Int32 value ) {
if ( value > 0 ) m_age = value;
}
}
property String^ Name;
Animal ( String^ name, Int32 age ) {
this->Name = name;
this->Age = age;
}
void Talk( ) {
Console::WriteLine( "私は{0}。年は{1}だよ。",
this->Name, this->Age);
}
};
public ref class Bird : Animal
{
public:
Bird ( String^ name, Int32 age ) : Animal( name, age ) { }
};
public ref class Human : Animal
{
public:
Human ( String^ name, Int32 age ) : Animal( name, age ) { }
};
みんな、前回のAnimalクラスの定義と何処が違うか分かったかな?public ref class Animal abstractの所のabstractキーワードが増えているピヨ。 このキーワードをつけることによりインスタンス化を禁止できるんだ。 じゃあ早速試そう。
Sample::Animal': 'abstract' として宣言されたクラスをインスタンス生成することはできません
Sample::Animal': 'abstract' として宣言されたクラスをインスタンス生成することはできません
Sample::Animal' : 参照型では 'new' を使用できません。'gcnew' を使用してください
Sample::Animal::Animal': 候補の関数はアクセス可能ではありません。
Sample::Animal::Animal': 候補の関数はアクセス可能ではありません。
うわぁー、エラーのお祭りやー。このように口うるさくC++/CLIコンパイラに怒られるよね。これでいいんだ。
このインスタンス化できないクラスの事を抽象クラス と呼ぶピヨ。
勘のいい人は気付いているとおもうけど、もちろん抽象化クラスはその他の利点も持っているピヨ。
それは、ヒ・ミ・ツ。というのは冗談で、多態性の時あわせて説明するピヨ。楽しみに待っててね。