2012-12-11 158 views
3

我沒有完全理解使用接口,所以我要問:-)重新實現繼承接口方法

我用一個BaseClass的,它實現了IBaseClass interface.These接口只包含一個聲明:

public interface IBaseClass 
{ 
    void Refresh(); 
} 

所以我在我的基類實現一個刷新方法:

public void Refresh() 
    { 
     Console.WriteLine("Refresh"); 
    } 

現在我想用從這些基類擴展一些類和實現IBaseClass接口:

public class ChildClass : BaseClass,IBaseClass 
    { 
    } 

但「刷新」到我的BaseClass的實現原因我不必再次實現該方法。我該怎麼做才能強制執行「刷新」到BaseClass的所有孩子以及所有子類的子類中。

感謝kooki

+0

你爲什麼要取消接受我的答案嗎?你有沒有找到更好的信息?如果是這樣,請發佈並接受您自己的回覆,以便將問題標記爲已回答。 –

回答

4

你不能強迫派生類重新實現在您指定的方式方法。您有三種選擇:

  1. 不要在基類中定義refresh。界面將強制子類實現它。
  2. 如果其接口的唯一目的是強制執行並聲明基類爲abstract以及refresh,那麼您將不會給出實現。
  3. 在基類中定義refreshvirtual。這允許覆蓋,但不會強制它們。這是ToString()的工作原理。

這都假設你的基類比單一的方法更大。如果你的代碼確實是你發佈的,那麼Oded的答案是最好的選擇。

3

簡單。不要提供基類實現,而必須在每個繼承類中實現該方法。爲實現這一

一種方法是使BaseClassabstract

public abstract BaseClass : IBaseClass 
{ 
    public abstract void Refresh(); 
} 
+0

但我也需要基類的實現。但是,如果沒有其他的可能性,我會實現一個名爲「BaseRefresh」的新方法,並且一個childclass可以在interface實現上調用它 – Kooki

+0

@Kooki - 爲什麼您還需要'BaseClass'中的實現? – Oded

+0

因爲有一些字段必須使用這些「刷新」設置到BaseClass中 – Kooki

1

如果你要提供一個默認的實現,這樣做在你的基類被標記爲虛擬的,所以你可以覆蓋在執行子類,如果你想。

否則將方法標記爲基類中的抽象方法,因此您的子類必須自己實現方法。

3

我該怎麼做才能強制執行「刷新」到BaseClass的所有孩子以及所有childclass的子類。

像這樣:

interface IBase 
{ 
    void Refresh(); 
} 

abstract class BaseClass : IBase 
{ 
    public abstract void Refresh(); 
} 

class ChildClass : BaseClass 
{ 
    public override void Refresh() 
    { 
     // Your code 
    } 
} 

你甚至可以省略接口(我的經驗法則:如果一個接口被正好一個類實現,傾倒的接口。不要緊貼界面炎。一個抽象類非常代表一個接口,另請參閱Interface vs Abstract Class (general OO))。

如果確實需要在基類的實現,把它做成這樣:

(abstract) class BaseClass (: IBase) 
{ 
    public virtual void Refresh() 
    { 
     // Your code 
    } 
} 

然後你就可以從你的派生類調用:

public override void Refresh() 
{ 
    // Your code 

    // optionally, to call the base implementation: 
    base.Refresh(); 
} 
0

可能關鍵詞可以幫助你;

namespace ConsoleApplication1 
{ 
    interface IBase 
    { 
     void Referesh(); 
    } 
    public class Base1 : IBase 
    { 
     public void Referesh() 
     { 
      Console.WriteLine("Hi"); 
     } 
    } 
    public class Class1 : Base1, IBase 
    { 
     public new void Referesh() 
     { 
      Console.WriteLine("Bye"); 
     } 

    } 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Class1 obj = new Class1(); 
      obj.Referesh(); 

      Console.ReadKey(); 
     } 
    } 
} 
+0

如果'Base1'顯式期望子類能夠實現他們自己的'Refresh'版本,'Base1'應該將方法定義爲'virtual'。 – comecme

+0

由於新關鍵字意味着方法隱藏,因此不是理想的解決方案。新關鍵字應該用於定義新的方法/屬性實現,其中原件不是虛擬的(不能覆蓋)。當你在設計類時,你知道方法將被覆蓋,然後使方法變爲虛擬。 – series0ne

1

讓我們看看這一步一步。

1:您有其定義像這樣定義的代碼契約的接口:

public interface IBase 
{ 
    void Refresh(); 
} 

2:您有它實現你的接口的基類。 (您會注意到刷新的實現是virtual。這使您可以在派生類中覆蓋此方法)。

class Base : IBase 
{ 
    public virtual void Refresh() 
    { 
     //Implementation 
    } 
} 

3:你擁有一種超類從基地派生。 (你會注意到派生類不需要明確地實現IBase,因爲它是在較低級別完成的,我會告訴你可以測試這個的完整性)。

class Child : Base 
{ 
    public override void Refresh() 
    { 
     base.Refresh(); //You can call this here if you need to perform the super objects Refresh() before yor own. 
     //Add your implementation here. 
    } 
} 

在這一點上,你可能會想; 「好的,那麼Child是如何實現IBase的?」。答案是它通過Base間接實現,並且因爲Child繼承Base,所以它也獲得了IBase的實現。

因此,如果你寫:

IBase instance = new Child(); 

這是完全合法的,因爲本質上,ChildIBase派生間接。

如果你想測試,你可以在你的代碼做到這一點:

bool canAssign = typeof(IBase).IsAssignableFrom(typeof(Child)); 
//canAssign should be true as Child can be assigned from IBase.