覆盖在接口中声明的方法实现

时间:2012-09-07 09:03:49

标签: c# inheritance interface

我有一个包含多种方法的界面。

interface IMyInterface
{
    //...
    void OnItemClicked()
    //...
}

一个实现

class MyClass : IMyInterface
{
    //Other methods
    public void OnItemClicked(){ /*...*/ } 
}

现在,除了MyClass之外,我希望有一个类似于OnItemClicked()的类,我希望对此方法进行一些修改。

我想继承覆盖,但我不想更改MyClass(例如:public virtual void OnItemClicked()...)因为它不是我的实施,

我不想再次实现IMyInterface,因为OnItemClicked()是要修改的MyClass的唯一部分。

我还有其他办法吗?

4 个答案:

答案 0 :(得分:16)

由于您正在实现接口,因此您可能希望保留多态性。如果不用虚拟的方法来修改基类,就不可能覆盖这个方法,所以你必须使用new而不是像Tigran所写的虚拟。

这意味着编写这种代码但只执行方法的基本版本:

List<MyClass> aList = new List<MyClass>();
aList.Add(new MyClass());
aList.Add(new MyNewClass());
foreach (MyClass anItem in aList)
    anItem.OnItemClicked();

要执行正确的代码,您应该编写如下的丑陋代码:

List<MyClass> aList = new List<MyClass>();
aList.Add(new MyClass());
aList.Add(new MyNewClass());
foreach (MyClass anItem in aList)
{
    MyNewClass castItem = anItem as MyNewClass;
    if (castItem != null)
        castItem.OnItemClicked();
    else
        anItem.OnItemClicked();
}

无论如何,有一种方法可以让你的类在分配给声明为IMyInterface的变量时执行正确的方法。要做的是显式实现要覆盖的接口部分,在您的情况下是OnItemClicked方法。代码如下:

public class MyNewClass : MyClass, IMyInterface // you MUST explicitly say that your class implements the interface, even if it's derived from MyClass
{
    public new void OnItemClicked() //NEW keyword here you have the overridden stuff
    { 
        /*...*/ 
    } 

    void IMyInterface.OnItemClicked() // No need for public here (all interfaces's methods must be public)
    { 
        this.OnItemClicked(); 
    } 
}

这样:

 MyClass cl = new MyNewClass(); 
 cl.OnItemClicked();

执行基本方法

 MyNewClass cl = new MyNewClass(); 
 cl.OnItemClicked();

执行派生类

的方法
 IMyInterface cl = new MyNewClass(); 
 cl.OnItemClicked();

执行派生类的方法,并在运行时绑定。这意味着您可以像这样编写我的初始示例的代码并执行正确的方法:

List<IMyInterface> aList = new List<IMyInterface>();
aList.Add(new MyClass());
aList.Add(new MyNewClass());
foreach (IMyInterface anItem in aList)
    anItem.OnItemClicked();

答案 1 :(得分:5)

您可以从MyClass

派生
public class MyNewClass : MyClass
{
    public new void OnItemClicked(){ /*...*/ } //NEW keyword
}

唯一的事情,注意这样你就不会支持多态性。

更清楚:

     MyClass cl = new MyNewClass(); 
     cl. MyMethod();

即使真实的对象类型为MyClass,也会调用MyNewType方法。 为了能够调用我们想要的东西,我们必须明确地定义类型

     MyNewClass cl = new MyNewClass(); 
     cl. MyMethod(); //WILL CALL METHOD WE WANT

答案 2 :(得分:3)

最简单的方法是使用“has-a”创建一个模仿“is-a”的新类:

public interface IMyInterface
{
    void OnItemClicked();
    void OnItemHover();
    void OnItemDoubleClicked();
}

public class MyNewClass : IMyInterface
{
    private IMyInterface _target;

    public MyNewClass(IMyInterface target)
    {
        _target = target;
    }

    public void OnItemClicked()
    {
        // custom functionality
    }

    public void OnItemHover()
    {
        _target.OnItemHover();
    }

    public void OnItemDoubleClicked()
    {
        _target.OnItemDoubleClicked();
    }
}

答案 3 :(得分:1)