好奇心から、基本クラスの抽象メソッドをオーバーライドして、実装の抽象メソッドをオーバーライドしようとしました。以下のように:
public abstract class FirstAbstract
{
public abstract void SomeMethod();
}
public abstract class SecondAbstract : FirstAbstract
{
public abstract override void SomeMethod();
//?? what sense does this make? no implementaion would anyway force the derived classes to implement abstract method?
}
C#コンパイラが「抽象オーバーライド」を記述できる理由を知りたいと思っています。冗長ではないですか?このようなことを行うには、コンパイル時エラーになるはずです。それはいくつかのユースケースに役立ちますか?
関心をお寄せいただきありがとうございます。
これの便利な例があります Microsoft Docs -基本的に、派生クラスにメソッドの新しい実装を提供させることができます。
public class D
{
public virtual void DoWork(int i)
{
// Original implementation.
}
}
public abstract class E : D
{
public abstract override void DoWork(int i);
}
public class F : E
{
public override void DoWork(int i)
{
// New implementation.
}
}
仮想メソッドが抽象として宣言されている場合でも、抽象クラスから継承するクラスには仮想メソッドです。 抽象メソッドを継承するクラスは、メソッドの元の実装にアクセスできません-前の例では、クラスFのDoWorkはクラスDのDoWorkを呼び出すことができません。このようにして、抽象クラスは派生クラスに仮想メソッドの新しいメソッド実装を提供するように強制できます。
派生クラスでの適切なToString()
実装を保証するのに本当に便利です。抽象基本クラスがあり、アクティブに使用しているため、すべての派生クラスで意味のあるToString()
実装を定義したいとします。あなたは_abstract override
_でとてもエレガントにそれを行うことができます:
_public abstract class Base
{
public abstract override string ToString();
}
_
ToString()
が何らかの方法(ユーザーへの出力の書き込みなど)で基本クラスで使用されることは、実装者にとって明確なシグナルです。通常、彼らはこのオーバーライドを定義することを考えません。
興味深いことに、C#コンパイラのRoslynバージョンには、抽象的なオーバーライドメソッドが含まれています。
SecondAbstract
が3つのクラス階層の真ん中にあり、そのベースFirstAbstract
からいくつかの抽象メソッドを実装し、他のいくつかのメソッドXを子ThirdAbstract
から実装することを想像してみてください。
この場合、SecondAbstract
は実装を提供したくないため、メソッドXをabstract
で装飾する必要があります。同時に、新しいメソッドXを定義していないため、override
で装飾することを余儀なくされていますが、Xの実装の責任をその子に移したいと考えています。したがって、abstract override
。
一般に、abstract
とoverride
でモデル化された概念は直交しています。最初のメソッドは派生クラスにメソッドの実装を強制しますが、2番目のメソッドはメソッドが基本クラスで指定されたものと同じであり、new
ではないことを認識します。
したがって:
abstract
のみ:派生クラスは実装する必要がありますoverride
のみ:基本クラスで定義されたメソッドの実装abstract override
:派生クラスは、基本クラスで定義されたメソッドを実装する必要がありますSomeMethod
でSecondAbstract
をabstract override
として宣言しなかった場合、コンパイラーはそのクラスにメソッドの実装が含まれていると想定します。 abstract override
を使用すると、SecondAbstract
自体ではなく、SecondAbstract
から派生したクラスに実装を含める必要があることは明らかです。
お役に立てれば...
このデザインパターンは、テンプレートメソッドパターンと呼ばれます。
単純な、ソフトウェア以外の例:戦車、ジェット、兵士、戦艦などの軍事ユニットがたくさんあります。これらはすべて、いくつかの一般的な方法を実装する必要がありますが、実装方法は大きく異なります。
等...
これは、子クラスでは基本クラスと同じ名前のabstract
メソッドを使用できないためです。 override
は、基本クラスの動作をオーバーライドしていることをコンパイラーに通知します。
これがあなたが探しているものであることを願っています。