0

さて、抽象的な関係「IS-A」とインターフェース「HAS-A」の機能について疑問があります。

たとえば、次のクラスがあります。

public interface IReport
{
    int code            { get; set; }
    String description  { get; set; }

    void SetReport(String description, int code);
    void DeleteReport();
}

public abstract class BugReport : IReport
{
    public int? code           { get; set; }
    public String description { get; set; }

    public void IReport.SetReport(String description, int code)
    {
        this.description = description;
        this.code = code;
    }

    public void IReport.DeleteReport()
    {
        this.description = "";
        this.code = null;
    }
}

BugReport クラスの実装は常に同じであることはわかっていますが、必要に応じて子クラスで拡張できます。この基準は、たとえばこのクラスで使用された場合、抽象クラスの「使用法」には一致しますが、「IS-A」関係には一致しません。

public abstract Parser : BugReport
{
}

私のパーサーは BugReport ですか? 明らかにそうではありませんが、BugReport をインターフェイスとして作成する場合、継承元のクラス全体に機能を実装する必要があるため、これが最も論理的な選択のようです。だから私が間違っていることは、IS-A関係の不一致とは無関係に抽象を使用し続ける必要がありますか、それともインターフェイスに切り替える必要がありますか?

4

3 に答える 3

1

まず、これは冗長に思えます。

int code            { get; set; }
String description  { get; set; }

void SetReport(String description, int code);

プロパティ セッターとそれらすべてを設定するための特殊なメソッドを用意するのは完全に冗長です。プロパティを追加するとどうなりますか? 変わりSetReportますか?この方法を使用すると、変更のカスケードが発生しますか? 新しいプロパティに対応し、クラスをさらに複雑にするために 3 番目の引数を取るオーバーロードを追加しますか?

インターフェイスをシンプルに保ちます。何かを行うための 1 つの方法を提供します。そうしないと、クラスの消費者を混乱させるだけです。

それを超えて、あなたが a が何であるかを提供していない場合Parser、それが BugReport であるかどうかは誰にも言えません。しかし、純粋に語彙に基づくと、ノーと言うでしょう。私が知っている辞書には、BugReport=Parser はありません。

于 2013-07-19T01:37:20.180 に答える
0

また、あなたの質問に基づいて、IS-A と HAS-A を誤解していると思います。

HAS-A 関係の例をまだ示していません。上記のコードの書き方では、BugReport は IReport であり、Parser は BugReport (したがって IReport でもあります) です。

この場合に has-a 関係を行う方法は、Parser が IReport であるプロパティを持っている場合です。例えば:

public class Parser 
{
   public Parser(IReport reporter)
   {
       this.Report = reporter;
   }

   public IReport Report { get; set; }
}
于 2013-07-19T01:47:03.397 に答える