web-dev-qa-db-ja.com

抽象クラスがすでにある場合、インターフェイスを定義することは理にかなっていますか?

デフォルト/共有機能を備えたクラスがあります。私はabstract classを使用しています:

public interface ITypeNameMapper
{
    string Map(TypeDefinition typeDefinition);
}

public abstract class TypeNameMapper : ITypeNameMapper
{
    public virtual string Map(TypeDefinition typeDefinition)
    {
        if (typeDefinition is ClassDefinition classDefinition)
        {
            return Map(classDefinition);
        }
        ...

        throw new ArgumentOutOfRangeException(nameof(typeDefinition));
    }

    protected abstract string Map(ClassDefinition classDefinition);
}

ご覧のとおり、私はITypeNameMapperインターフェースも持っています。抽象クラスTypeNameMapperまたはabstract classで十分であれば、このインターフェイスを定義しても意味がありますか?

この最小限の例のTypeDefinitionも抽象的です。

12
Konrad

C# は、インターフェースを除いて多重継承を許可しないためです。

したがって、TypeNameMapperとSomethingelseMapperの両方であるクラスがある場合、次のことができます。

class MultiFunctionalClass : ITypeNameMapper, ISomethingelseMapper 
{
    private TypeNameMapper map1
    private SomethingelseMapper map2

    public string Map(TypeDefinition typeDefinition) { return map1.Map(typeDefintion);}

    public string Map(OtherDef otherDef) { return map2.Map(orderDef); }
}
31
Ewan

インターフェースと抽象クラスは異なる目的を果たします:

  • Interfaces APIを定義し、実装ではなくクライアントに属します。
  • クラスが実装を共有している場合は、abstractクラスの恩恵を受けることができます。

あなたの例では、interface ITypeNameMapperはクライアントのニーズを定義し、abstract class TypeNameMapperは値を追加していません。

1
Geoffrey Hale

質問に明確に答えたい場合、著者は「抽象クラスTypeNameMapperまたは抽象クラスがすでに十分にある場合、このインターフェイスを定義することは理にかなっていますか?」と述べています。

答えは「はい」と「いいえ」です。はい、抽象基本クラスがすでにある場合でもインターフェイスを作成する必要があります(クライアントコードで抽象基本クラスを参照してはならないため)。作成していないはずなので、いいえインターフェースがない場合の抽象基本クラス。

作成しようとしているAPIを十分に検討していないことは明らかです。最初にAPIを考え出し、必要に応じて部分的な実装を提供します。抽象基本クラスがコードで型チェックを行うという事実は、それが正しい抽象化ではないことを伝えるのに十分です。

OODのほとんどのことと同様に、溝にいてオブジェクトモデルを適切に実行すると、コードは次に何が起こるかを通知します。インターフェースから始めて、必要なクラスにそのインターフェースを実装します。同様のコードを書いている場合は、抽象基本クラスに抽出します。重要なのはインターフェースです。抽象基本クラスは単なるヘルパーであり、複数存在する場合があります。

0

インターフェースの概念全体は、共有APIを持つクラスのファミリーをサポートするために作成されました。

これは、インターフェイスを使用すると、その仕様の実装が複数存在する(または存在することが予想される)ことを意味します。

DIフレームワークは、実装が1つしかない場合でも、多くの場合インターフェースを必要とするという点で、水を濁らせています。私にとって、これは、ほとんどの場合、新しい呼び出しのより複雑で遅い手段にとっては不合理なオーバーヘッドですが、それはそれが何であるかです。

答えは質問自体にあります。抽象クラスがある場合は、共通のAPIを使用して複数の派生クラスを作成する準備をしています。したがって、インターフェースの使用が明確に示されます。

0