2012-12-11 151 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.