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 作为一个接口,我将不得不在我继承的所有类中实现该功能。那么我做错了什么,我应该继续使用独立于 IS-A 关系不匹配的抽象还是应该切换到接口?

4

3 回答 3

1

首先,这对我来说似乎是多余的;

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

void SetReport(String description, int code);

拥有属性设置器和专门的方法来设置它们是完全多余的。如果添加属性会发生什么?你改变了吗SetReport吗?使用这种方法会导致一连串的变化?您是否添加了一个带有第三个参数的重载来满足新属性并使类进一步复杂化?

保持界面简洁;提供一种方法来做某事,否则你只会混淆班级的消费者。

除此之外,鉴于您不知道 aParser是什么,那么没有人可以说它是否是 BugReport。但纯粹基于词典,我会说不。在我所知道的任何字典中都没有 BugReport=Parser。

于 2013-07-19T01:37:20.180 回答
0

您应该考虑组合而不是继承。创建一个BugReport类,并在你的Parser类中使用它的一个实例来获得你想要的功能,而不是通过继承来获得功能。

您可以在子类上扩展类的功能BugReport,并根据需要将它们注入您的Parser类。

于 2013-07-19T01:36:11.280 回答
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 回答