C# - クラス - 継承 その2
クラスの継承の続き
昨日の日記では、派生クラスのコンストラクタを実行すると暗黙的に基底クラスの引数なしのコンストラクタが実行されたが、これでは都合が悪いので基底クラスの特定のコンストラクタを実行する様にもできる。
public 派生クラス名(引数リスト) : base(基底クラスのコンストラクタの引数リスト)
メソッドの継承について、同名のメソッドを基底クラスとは全く関係のない機能にする場合は派生クラスのメソッドにnewキーワードを付加する。これで基底クラス側のメソッドを隠蔽することができる。
基底クラスのメソッドの機能を変更したり呼び出したりする場合は、基底クラスが側のメソッドにvirtualキーワードを、派生クラス側にoverrideキーワードを付加する。
基底クラスの同名メソッドを実行する場合は
base.メソッド名(引数リスト)
とする。
なお、継承されたくないクラスについては、sealedキーワードを付けてクラスの定義を行う
sealed class クラス名
using System; //クラスの継承 class MyClass { //privateだと継承したクラスからアクセスできない protected int d1; public MyClass(int x) { Console.WriteLine("MyClassのコンストラクタ実行"); Console.WriteLine(" 引数は {0} です", x); this.d1 = x; } //派生クラスでoverrideされるのでvirtualをつける public virtual void PrintVars() { Console.WriteLine("MyClassの変数表示"); Console.WriteLine(" d1 : {0}", d1); } public void PrintD1() { Console.WriteLine("MyClassの変数(d1)表示"); Console.WriteLine(" d1 : {0}", d1); } public void PrintMSG() { Console.WriteLine("これはMyClassのインスタンスです。"); } } //MyClassを継承 class MyClassA : MyClass { private int d2; //明示的に基底クラスのコンストラクタを(引数付で)呼ぶ public MyClassA(int x, int y) : base(x) { Console.WriteLine("MyClassAのコンストラクタ実行"); Console.WriteLine(" 引数は {0} です", x); Console.WriteLine(" 引数は {0} です", y); this.d2 = y; } //基底クラスの(virtual付)同名メソッドを変更定義する public override void PrintVars() { //基底クラスのメソッド呼び出し base.PrintVars(); Console.WriteLine("MyClassAの変数表示"); Console.WriteLine(" d2 : {0}", d2); } // newで基底クラスの同名メソッドを隠蔽して上書きする public new void PrintMSG() { Console.WriteLine("これはMyClassAのインスタンスです。"); } } class MyMain { static void Main(string[] args) { MyClassA m = new MyClassA(1, 2); //規定クラスのメソッドを変更したメソッド m.PrintVars(); //基底クラスのメソッド呼び出しができる m.PrintD1(); //newで隠蔽したメソッドの呼び出し m.PrintMSG(); } }
実行結果
MyClassのコンストラクタ実行 引数は 1 です MyClassAのコンストラクタ実行 引数は 1 です 引数は 2 です MyClassの変数表示 d1 : 1 MyClassAの変数表示 d2 : 2 MyClassの変数(d1)表示 d1 : 1 これはMyClassAのインスタンスです。