web-dev-qa-db-ja.com

C#での「抽象オーバーライド」の使用は何ですか?

好奇心から、基本クラスの抽象メソッドをオーバーライドして、実装の抽象メソッドをオーバーライドしようとしました。以下のように:

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#コンパイラが「抽象オーバーライド」を記述できる理由を知りたいと思っています。冗長ではないですか?このようなことを行うには、コンパイル時エラーになるはずです。それはいくつかのユースケースに役立ちますか?

関心をお寄せいただきありがとうございます。

47

これの便利な例があります 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を呼び出すことができません。このようにして、抽象クラスは派生クラスに仮想メソッドの新しいメソッド実装を提供するように強制できます。

59
BrokenGlass

派生クラスでの適切なToString()実装を保証するのに本当に便利です。抽象基本クラスがあり、アクティブに使用しているため、すべての派生クラスで意味のあるToString()実装を定義したいとします。あなたは_abstract override_でとてもエレガントにそれを行うことができます:

_public abstract class Base
{
    public abstract override string ToString();
}
_

ToString()が何らかの方法(ユーザーへの出力の書き込みなど)で基本クラスで使用されることは、実装者にとって明確なシグナルです。通常、彼らはこのオーバーライドを定義することを考えません。

43
ghord

興味深いことに、C#コンパイラのRoslynバージョンには、抽象的なオーバーライドメソッドが含まれています。

http://ericlippert.com/2011/02/07/strange-but-legal/

12
Eric Lippert

SecondAbstractが3つのクラス階層の真ん中にあり、そのベースFirstAbstractからいくつかの抽象メソッドを実装し、他のいくつかのメソッドXを子ThirdAbstractから実装することを想像してみてください。

この場合、SecondAbstractは実装を提供したくないため、メソッドXをabstractで装飾する必要があります。同時に、新しいメソッドXを定義していないため、overrideで装飾することを余儀なくされていますが、Xの実装の責任をその子に移したいと考えています。したがって、abstract override

一般に、abstractoverrideでモデル化された概念は直交しています。最初のメソッドは派生クラスにメソッドの実装を強制しますが、2番目のメソッドはメソッドが基本クラスで指定されたものと同じであり、newではないことを認識します。

したがって:

  • どちらのキーワード:「単純な」方法
  • abstractのみ:派生クラスは実装する必要があります
  • overrideのみ:基本クラスで定義されたメソッドの実装
  • abstract override:派生クラスは、基本クラスで定義されたメソッドを実装する必要があります
6
Jon

SomeMethodSecondAbstractabstract overrideとして宣言しなかった場合、コンパイラーはそのクラスにメソッドの実装が含まれていると想定します。 abstract overrideを使用すると、SecondAbstract自体ではなく、SecondAbstractから派生したクラスに実装を含める必要があることは明らかです。

お役に立てれば...

0
Francois

このデザインパターンは、テンプレートメソッドパターンと呼ばれます。

テンプレートメソッドのウィキペディアページ

単純な、ソフトウェア以外の例:戦車、ジェット、兵士、戦艦などの軍事ユニットがたくさんあります。これらはすべて、いくつかの一般的な方法を実装する必要がありますが、実装方法は大きく異なります。

  • Move()
  • 攻撃()
  • 退却()
  • 残り()

等...

0
noctonura

これは、子クラスでは基本クラスと同じ名前のabstractメソッドを使用できないためです。 overrideは、基本クラスの動作をオーバーライドしていることをコンパイラーに通知します。

これがあなたが探しているものであることを願っています。

0
Amar Palsapure