hakeの日記

Windows環境でプログラミングの勉強をしています。

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のインスタンスです。