2015-07-11 66 views
0

我有一個關於如何在我的C#程序中正確使用接口和抽象類的問題。我有許多獨立的「模塊」(BeatsPerMinuteMeasurement,MouseRecorder,ClipboardHistory等)。他們都至少有一個面板(UserControl)和一個「邏輯」(普通類)。首先,沒有繼承。但是,現在我重寫這樣的:( - >)指繼承:使用獨立「模塊」的接口和基類

  • SomeLogic - > BaseLogic - > IBaseLogic
  • SomePanel - > BasePanel - >用戶控件,IBasePanel

的問題:這是一個好辦法嗎?這裏是我的面板的代碼(這是不奇怪的,因爲繼承錯誤的工作):

interface IBasePanel { 
    void RegisterEvents(); 
    void Close(); 
} 

abstract class BasePanel : UserControl, IBasePanel { 
    public BasePanel() { 
     InitializeComponent(); 
     RegisterEvents(); //Compiler error, compiler cant find it 
    } 

    public abstract void InitializeComponent(); 
} 

class MouseKeyRecord_Panel : BasePanel { 
    //GUI variables (buttons/labels etc.) 

    public MouseKeyRecord_Panel() { 

    } 

    protected override void RegisterEvents() { 
     //Register EventHandler for buttons etc. 
    } 

    protected override void InitializeComponent() { 
     //Visual Studio auto generated GUI 
    } 

    public override void Close() { 
     //Closing Threads etc. 
    } 
} 

編輯1 解決。 我刪除了界面,現在它正在工作。我想我以錯誤的方式使用了接口。我仍然不知道何時使用抽象類以及何時使用接口。因爲,因爲編譯器規定的RegisterEvents()Close()所需的實現並沒有在你的BaseClass實施出現時

+0

如果你沒有繼承,你爲什麼要開始做呢?目前不工作嗎?無論你試圖達到什麼樣的目標,都可以用組合而不是繼承來解決。 –

+0

好吧,它的工作,但我想重新設計它們使其「更好」。他們都有一些共同的東西。他們都有一個Close,InitializeComponent和RegisterEvents方法。我通過這種方式瞭解到:如果您看到類具有相同的方法,請使用基類,以便每個需要該方法的類都可以繼承它。 – Need

回答

0

你的編譯器錯誤。

如果你想推遲實施的子類,然後以正確的方式來實現在基類的接口是聲明abstract實現,就像你爲InitializeComponent()

abstract class BasePanel : UserControl, IBasePanel { 
    public BasePanel() { 
     InitializeComponent(); 
     RegisterEvents(); 
    } 

    public abstract void InitializeComponent(); 
    public abstract void RegisterEvents(); 
    public abstract void Close(); 
} 

這就是說,注意只是簡單地做出上述更改就不會獲得您發佈的代碼進行編譯。隱式實現的接口必須使用public成員來實現。您無法使RegisterEvents()成爲protected成員。另一方面,如果你真的希望它是一個protected成員,那麼它可能不應該在一個接口中,因爲接口的設計成員是公開的。

本着同樣的,你也有與InitializeComponent()方法,您已在基類public聲明一個問題,但在派生類MouseKeyRecord_Panelprotected。您無法更改虛擬成員覆蓋的可訪問性。可以使覆蓋爲public方法,也可以將基類聲明更改爲protected

很可能是你仍然不知道何時使用抽象類和接口。但第一步是知道如何。 :)至於「何時」,簡單的答案是抽象類和接口非常相似;主要的例外是一個抽象類可以(並且一般地)包括一些實際的實現,除了聲明的接口(即抽象類的成員實際上是該類聲明的接口,注意不同於接口,abstract成員抽象類不需要是public)。當然,作爲一個實際的類,任何給定的類型最多可以繼承一個抽象類(如果它已經繼承了一些其他類,則它們都不會繼承)。你可以實現儘可能多的接口,你想/需要(有人將此描述爲繼承接口,但我傾向於考慮繼承實現和實現接口)。

更深入的解釋是恕我直言對於堆棧溢出來說太廣泛了,最好留給Web上的文本書籍,博客和其他文章(包括MSDN上的C#文檔)中的許多資源。