継承 (Inheritance)

class BaseClass
{
}

class SubClass : BaseClass
{
}

継承方法の指示

  • virtual … 派生クラスに、オーバーライドを許可
  • abstract … 派生クラスに、オーバーライドを強制
抽象メソッドと仮想メソッド - 継承 (C# プログラミング ガイド) | Microsoft Docs

virtual

class BaseClass
{
    public         void Method1() { }
    public virtual void Method2() { }
    public virtual void Method3() { }
}

class SubClass : BaseClass
{
    public          void Method1() { } // CS0108 'SubClass.Method1()' は継承されたメンバー 'BaseClass.Method1()' を非表示にします。非表示にする場合は、キーワード new を使用してください。
    public          void Method2() { } // CS0114 'SubClass.Method2()' は継承されたメンバー 'BaseClass.Method2()' を非表示にします。現在のメンバーでその実装をオーバーライドするには、override キーワードを追加してください。オーバーライドしない場合は、new キーワードを追加してください。
    public override void Method3() { } // OK
}

abstract

class BaseClass1
{
    public abstract void Method1(); // CS0513 'BaseClass1.Method1()' は抽象ですが、非抽象クラスの 'BaseClass1' に含まれています。
}

abstract class BaseClass2
{
    public abstract void Method1() { } // CS0500 'BaseClass2.Method1()' は abstract に指定されているため本体を宣言できません。
    public abstract void Method2();    // OK
}

class SubClass : BaseClass2 // CS0534 'SubClass' は継承抽象メンバー 'BaseClass2.Method1()' を実装しません。
{
    public          void Method1() { } // CS0114 'SubClass.Method1()' は継承されたメンバー 'BaseClass2.Method1()' を非表示にします。現在のメンバーでその実装をオーバーライドするには、override キーワードを追加してください。オーバーライドしない場合は、new キーワードを追加してください。
    public override void Method2() { } // OK
}

継承の実装

override … メソッドの拡張

virtualやabstractで宣言されているメソッドを、拡張して実装します。

abstract class BaseClass1
{
    public          void Method1() { }
    public virtual  void Method2() { }
    public abstract void Method3();
}

class SubClass : BaseClass1
{
    public override void Method0() { } // CS0115 'SubClass.Method0()': オーバーライドする適切なメソッドが見つかりませんでした。
    public override void Method1() { } // CS0506 'SubClass.Method1()': 継承されたメンバー 'BaseClass1.Method1()' は virtual、abstract または override に設定されていないためオーバーライドできません。
    public override void Method2() { } // OK
    public override void Method3() { } // OK
}

new … メソッドの隠蔽

class BaseClass1
{
    protected virtual void Method1() { }
    protected virtual void Method2() { }
    protected virtual void Method3() { }
}

class SubClass : BaseClass1
{
    public    override void Method1() { } // CS0507 'SubClass.Method1()': 'protected' の継承メンバー 'BaseClass1.Method1()' をオーバーライドするときに、アクセス修飾子を変更できません。
    public    new      void Method2() { } // OK
    protected override void Method3() { } // OK
}

overrideとnewの相違

基本クラスと、それを継承した派生クラスを定義します。

class BaseClass
{
    public virtual void Method1() { Console.WriteLine("Base - Method1"); }
    public virtual void Method2() { Console.WriteLine("Base - Method2"); }
}

class SubClass : BaseClass
{
    public override void Method1() { Console.WriteLine("Sub - Method1"); }
    public new      void Method2() { Console.WriteLine("Sub - Method2"); }
}

次の3通りの場合について、それぞれ呼ばれるメソッドを確認します。

  1. 基本クラスに、基本クラスのインスタンスを格納
  2. 派生クラスに、派生クラスのインスタンスを格納
  3. 基本クラスに、派生クラスのインスタンスを格納
BaseClass c1 = new BaseClass();
c1.Method1(); // Base - Method1 … 基本クラスのメソッドが呼ばれる
c1.Method2(); // Base - Method2

SubClass c2 = new SubClass();
c2.Method1(); // Sub - Method1 … 派生クラスのメソッドが呼ばれる
c2.Method2(); // Sub - Method2

BaseClass c3 = new SubClass();
c3.Method1(); // Sub - Method1 … overrideで拡張されていると、派生クラスのメソッドが呼ばれる
c3.Method2(); // Base - Method2 … newで隠蔽されていると、基本クラスのメソッドが呼ばれる
MSDN (Microsoft Developer Network) から検索