C#をつつく21-継承1-継承禁止。もうそれ以上は・・・。
インドリィちゃん「前から気になっていたんだけど。」
インドリ「うぁ!出たぁ~」
インドリィちゃん「失礼ね。まぁいいわ。 それよりも、貴方が作ったサンプルプログラムのAnimalクラスに不思議な点があるんだけど。」
インドリ「どこどこ?」
インドリィちゃん「Talkメソッドってあるけど、これっておかしくない?」
インドリ「ううん。これはその種族の言葉で喋っているんだ。」
インドリィちゃん「それなら納得。じゃあ、もっと分かりやすくするべきよ。」
インドリ「相変わらずドリィちゃんは完ぺき主義だなぁ。」
インドリィちゃん「そうかしら?。読者もきっとツッコミを入れていたはずよ。」
インドリ「わかったよ。じゃあ実装するね。」
ということで毎度お馴染みAnimal抽象クラスを改良したピヨ。みんな見てね。
public abstract class Animal
{
private string m_Name;
public string Name {
get { return m_Name; }
}
private int m_Age;
public int Age {
get { return m_Age; }
set {
if ( value > 0 ) m_Age = value;
}
}
private string m_password;
public string Password {
set { m_password = value; }
}
public Animal( string name, int age ) {
this.m_Name = name;
this.Age = age;
}
//このメソッドを修正
public virtual void Talk( ) {
Console.WriteLine( "私は{0}。年は{1}だよ。(by {2}語)",
this.m_Name, this.m_Age, this.GetType().Name );
}
public abstract void Move( );
}
早速F5だぁ。これでボクがBird語(鳥語)を喋っていることが確認できるよ。
今回注目するべきところは
this.GetType().Nameピヨ。前から何度かthisキーワードを使っていたけども、 それを説明していなかったので今するピヨ。 今サンプルプログラムを実行すると・・・
私はインドリ。年は29だよ。(by Bird語)
って表示される。この結果から推測できると思うけど、 thisキーワードは インスタンス自身を指し示しているんだ。 それで、GetType()メソッドは自身の型を返すメソッドだから、 Birdクラスを表すType型のが返されるからBirdと表示されるんだ。 これも多態性を表すための機能といえるピヨ。
じゃあ、今回はこれで
インドリィちゃん「ちょっと待ちなさい。貴方と私は日本語で会話しているはずよ。」
インドリ「ええっと、そうだけど。ドリィちゃんどうしたの?」
インドリィちゃん「それっておかしいわ。貴方は種類わかんないけど一応鳥よね?」
インドリ「そうだピヨ。でもボクは人間の言葉が理解できるよ。生まれつき喋れるんだ。」
インドリィちゃん「普通の鳥は人語を喋らないわ。ちょっとPC貸して。こうするべきよ。」
public abstract class Animal
{
private string m_Name;
//オーバーライドできるように変更
public virtual string Name {
get { return m_Name; }
}
private int m_Age;
public int Age {
get { return m_Age; }
set {
if ( value > 0 ) m_Age = value;
}
}
private string m_password;
public string Password {
set { m_password = value; }
}
public Animal( string name, int age ) {
this.m_Name = name;
this.Age = age;
}
public virtual void Talk( ) {
Console.WriteLine( "私は{0}。年は{1}だよ。(by {2}語)",
this.m_Name, this.m_Age, this.GetType().Name );
}
public abstract void Move( );
}
public sealed class InDori : Bird
{
//プロパティをオーバーライド
public override string Name {
get { return "インドリ"; }
}
//コンストラクタをオーバーライド
//こうやってプロパティ値が自動的に決まるように出来る
public InDori( int age ) : base( "インドリ", age ) {}
public override void Talk( ) {
Console.WriteLine( "ボクはインドリ。年は{0}だよ。(by 人語)", this.Age);
}
}
class Program
{
static void Main( string[ ] args ) {
InDori tori = new InDori( 29 );
tori.Move( );
Console.WriteLine( "{0}参上!", tori.Name);
tori.Talk( );
Console.WriteLine( );
Human dre = new Human( "ドリィちゃん", 16 );
dre.Move( );
Console.WriteLine( "{0}参上!", dre.Name );
dre.Talk( );
Console.WriteLine( );
}
}
インドリ「へぇ~コンストラクタをそんな風にオーバーライドできるんだ。ちょっとやり過ぎな気もするけどね。あれっ? sealedって何?」
インドリィちゃん「それは、それ以上派生クラスを作れないようにするキーワードよ。
貴方みたいのがいっぱい居るわけないじゃない。
これでより特殊な鳥クラスは作れなくなったわ。 」
インドリ「ええっそりゃないよ!!!ボクだって将来結婚して子供も産まれる筈だよ。」
インドリィちゃん「それでも貴方は例外中の例外だから、子供にそんな特技が遺伝しないでBirdクラスのインスタンスになる筈よ。」
インドリ「まぁ、そうかもしれないけど。納得いかないよ!」
インドリィちゃん「別に貴方一匹ぐらい特殊な存在が居てもいいじゃないの。」
インドリ「・・・」(じーん。感動したピヨ。案外ドリィちゃんっていい奴なんだな。そういえば、まともに相手してくれたのはドリィちゃんだけだったよ。)
インドリィちゃん「なっ何、感動してんのよ。当たり前のことじゃない。もぅ終わるわよ。」
テレたドリィちゃんによって強制終了。次回へ続く・・・