web-dev-qa-db-ja.com

インターフェイスを実装するc#抽象クラス

次のコードレイアウトは、フォーラムやその他のブログ投稿を読んで、いくつかの質問をするために改作しました。

public interface IService<T>
{
    int Add(T entity);
    void Update(T entity);
}

public abstract class ServiceBase<T> : IService<T>
{
    public int Add(T entity) { ... }
    public void Update(T entity) { ... }
}

public interface ICarService : IService<Car>
{
}

public class SomeBaseClass : ServiceBase<Car>, ICarService
{
    public int Add(Car entity);
    public void Update(Car entity);
}

私が理解していないのは、抽象クラスがインターフェースを実装することの利点です。私にとっては、それは少し反復的であると感じ、インターフェイスを実装する抽象クラスを持つことの利点を理解できません。

  1. なぜ抽象クラスServiceBase<T> IServiceインターフェイスを継承する必要なしに、そのまま定義しますか?これはコードを2倍にしますか?
  2. なぜSomeBaseClassICarServiceを実装する必要があるのですか? ServiceBaseで十分ではありませんか?
32
fes

Ad 1:追加の抽象基本クラスを使用すると、実装を中断することなくインターフェースを進化させることができます。抽象基本クラスがなく、インターフェースを拡張するとします。たとえば、新しいメソッドを追加してみましょう。次に、クラスがインターフェースを実装しなくなったため、実装が壊れました。

追加の抽象基本クラスを使用すると、これを分離できます。インターフェイスに新しいメソッドを追加すると、基本クラスに仮想実装を提供でき、すべてのサブクラスを同じままにして、新しいクラスに一致させることができます。後でインターフェイスします。

さらに、この組み合わせにより、(インターフェースを使用して)コントラクトを定義し、(抽象基本クラスを使用して)デフォルトのメカニズムを提供できます。デフォルトで大丈夫なら誰でも抽象基本クラスから継承できます。細かい部分まで細かく制御したい人は、手動でインターフェースを実装できます。

広告2:技術的な観点から、最終クラスにインターフェースを実装するための[〜#〜] need [〜#〜]はありません。しかし、これでも、物事を個別に進化させることができます。 CarServiceは確かにService<Car>、しかしそれはそれ以上かもしれません。たぶんCarServiceだけが、共通のインターフェースやサービスの基本クラスに入るべきではない、いくつかの追加のものが必要です。

それが理由だと思います;-)

33
Golo Roden