17

我有一个接口,里面有几个方法。

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

和一个实现

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

现在,我想要一个行为类似于MyClassexcept of的类OnItemClicked(),我想要对这个方法进行一些修改。

我想继承一个覆盖,但我不想更改MyClass(如:public virtualvoid OnItemClicked()...),因为它不是我的实现,

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

我还有其他方法吗?

4

4 回答 4

18

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

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

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();
于 2012-09-07T10:08:20.463 回答
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
于 2012-09-07T09:05:55.350 回答
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();
    }
}
于 2012-09-07T09:11:55.653 回答
1

使用模式桥http://en.wikipedia.org/wiki/Bridge_pattern

于 2012-09-07T09:06:52.793 回答