2013-07-19 76 views
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; 
    } 
} 

我知道我的錯誤報告類將始終相同的實現,但是我可以根據需要在子類擴展。如果用於例如在該類此標準將匹配的抽象類「用法」,而不是「是」的關係:

public abstract Parser : BugReport 
{ 
} 

是我的解析器錯誤報告?顯然不是,但它似乎是最合理的選擇,如果我讓我的BugReport作爲一個接口,我將不得不實現遍及我繼承的類的功能。所以我做錯了什麼,我應該繼續使用獨立於IS-A關係不匹配的抽象,否則我應該切換到接口?

+0

我沒有看到'[C++]'的問題? – Yakk

+0

我將刪除'C++'標籤,因爲這是純粹的'c#'問題 – billz

+0

C++不是C#。選擇適當的語言。 – user2246674

回答

0

你應該考慮構成的繼承。創建一個BugReport類,並在您的Parser類中使用它的一個實例來獲得所需的功能,而不是通過繼承獲取功能。

您可以擴展子類的BugReport類的功能,並根據需要將它們注入到Parser類中。

1

首先,這對我來說似乎是多餘的;

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

void SetReport(String description, int code); 

擁有屬性設置器和專門設置它們的方法是完全多餘的。如果你添加一個屬性會發生什麼?你改變SetReport?使用這種方法引起級聯變化?你是否添加了一個重載,該重載需要第三個參數來迎合新的屬性並使類更加複雜化?

保持界面簡單;提供一種做某事的方式,否則你只是混淆了班級的消費者。

除此之外,鑑於您不知道Parser是什麼,那麼沒有人可以說它是否是BugReport。但純粹基於詞彙,我會說不。在沒有字典中,我知道BugReport = Parser。

0

我也認爲你根據你的問題誤解了IS-A和HAS-A。

你還沒有給出一個HAS-A關係的例子。上面寫代碼的方式,BugReport是IReport,Parser是BugReport(因此也是IReport)。

在這種情況下,做一個有關係的方法是解析器有一個屬性是IReport。例如:

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

    public IReport Report { get; set; } 
}