class BaseClass { } class SubClass : BaseClass { }
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 }
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 }
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 }
派生クラスから、オーバーライドした基本クラス (基底クラス) のメソッドを呼び出せます。base キーワード - C# リファレンス | Microsoft Learn
public override void Method2() { base.Method2(); }
class BaseClass1 { protected virtual void Method1() { } protected virtual void Method2() { } protected virtual void Method3() { } protected virtual void Method4() { } } class SubClass : BaseClass1 { public override void Method1() { } // CS0507 'SubClass.Method1()': 'protected' の継承メンバー 'BaseClass1.Method1()' をオーバーライドするときに、アクセス修飾子を変更できません。 public new void Method2() { } // OK protected override void Method3() { } // OK protected new void Method4() { } // OK }
派生クラスでnewで非表示にしたメソッドの、アクセス修飾子を変更する場合を考えます。
class BaseClass1 { public void Method1() { Console.Write("Base - Method1"); } public void Method2() { Console.Write("Base - Method2"); } private void Method3() { Console.Write("Base - Method3"); } private void Method4() { Console.Write("Base - Method4"); } } class SubClass : BaseClass1 { public new void Method1() { Console.Write("Sub - Method1"); } private new void Method2() { Console.Write("Sub - Method2"); } public new void Method3() { Console.Write("Sub - Method3"); } // warning CS0109: メンバー 'SubClass.Method3()' は継承されたメンバーを非表示にしません。new キーワードは不要です。 private new void Method4() { Console.Write("Sub - Method4"); } // warning CS0109: メンバー 'SubClass.Method4()' は継承されたメンバーを非表示にしません。new キーワードは不要です。 public void Func() { this.Method1(); // Sub - Method1 this.Method2(); // Sub - Method2 … 派生クラスのメソッドへアクセス可能なため、それが呼ばれる this.Method3(); // Sub - Method3 this.Method4(); // Sub - Method4 } }
派生クラスのインスタンスから呼ぶ場合は、アクセス可能なメソッドが呼ばれます。
SubClass sub = new SubClass(); sub.Method1(); // Sub - Method1 sub.Method2(); // Base - Method2 … 派生クラスのメソッドはprivateなため、基本クラスのそれが呼ばれる sub.Method3(); // Sub - Method3 sub.Method4(); // error CS0122: 'SubClass.Method4()' はアクセスできない保護レベルになっています
基本クラスと、それを継承した派生クラスを定義します。
class BaseClass { public virtual void Method1() { Console.Write("Base - Method1"); } public virtual void Method2() { Console.Write("Base - Method2"); } } class SubClass : BaseClass { public override void Method1() { Console.Write("Sub - Method1"); } public new void Method2() { Console.Write("Sub - Method2"); } }
次の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で隠蔽されていると、基本クラスのメソッドが呼ばれる