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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12314990/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 22:51:09  来源:igfitidea点击:

Override method implementation declared in an interface

c#inheritanceinterface

提问by Miklós Balogh

I've got an interface with a several methods in it.

我有一个包含多种方法的接口。

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

And an implementation

和一个实现

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

Now, I want to have a class that behaves like MyClassexcept of OnItemClicked(), I want some modifications for this method.

现在,我想有一类表现得像MyClass除外OnItemClicked(),我要为这个方法进行一些修改。

I thought to inherit an override but I don't want to change the MyClass(like: public virtualvoid OnItemClicked()...) because its not my implementation,

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

I don't want to implement IMyInterfaceagain because the OnItemClicked() is the only part of MyClass to modify.

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

Do I have any other way to do it?

我还有其他方法吗?

采纳答案by Francesco Baruchelli

Since you are implementing an interface, polymorphism is probably something you'd like to keep. It's impossible to override the method without modyfing the base class with a virtual, so you must use new instead of virtual as Tigran wrote.

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

This means that writing this kind of code but only the base version of the method would be executed:

这意味着编写此类代码但只会执行该方法的基本版本:

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

To execute the right code you should write ugly code like this:

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

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();
}

Anyway there is a way to have your classes executing the right method when they are assigned to variables declared as IMyInterface. The way to go is to explicitly implement the part of the interface that you want to override, in your case the OnItemClicked method. The code is the following:

无论如何,有一种方法可以让您的类在分配给声明为 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(); 
    } 
}

In this way:

通过这种方式:

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

executes the base method

执行基本方法

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

executes the method of the derived class

执行派生类的方法

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

executes the method of the derived class and is bound at runtime. This means that you can write the code of my initial example like this and have the right methods executed:

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

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

回答by Tigran

you can derive from MyClass

你可以从 MyClass

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

The only thing, pay attention that in this way you do not supprot polymorphism.

唯一要注意的是,这种方式不支持多态性。

To be more clear:

更清楚一点:

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

this will call MyClassmethod, even if the realobject type is MyNewType. To be able to call what we want, we have to esplicitly define type

这将调用MyClass方法,即使实际对象类型是MyNewType. 为了能够调用我们想要的东西,我们必须明确定义类型

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

回答by armen.shimoon

The easiest way is to create a new class that mimics "is-a" using "has-a":

最简单的方法是创建一个使用“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();
    }
}