using System;
namespace random
{
interface IHelper
{
void HelpMeNow();
}
public class Base : IHelper
{
public void HelpMeNow()
{
Console.WriteLine("Base.HelpMeNow()");
}
}
public class Derived : Base
{
public new void HelpMeNow() ///this line
{
Console.WriteLine("Derived.HelpMeNow()");
}
}
class Test
{
public static void Main()
{
Derived der = new Derived();
der.HelpMeNow();
IHelper helper = (IHelper)der;
helper.HelpMeNow();
Console.ReadLine();
}
}
}
注释行中的新关键字让我有点困惑。它只是意味着它覆盖了基类中方法的实现。 为什么不使用 override 关键字?
最佳答案
它并没有真正覆盖它,而是隐藏它。给定对 Derived
对象的引用,Base
的 HelpMeNow
函数将不可访问1,并且 derivedObject.HelpMeNow()
将调用 Derived
的实现。
这与覆盖虚函数不同,HelpMeNow
不是。如果 Derived
对象存储在对 Base
或 IHelper
的引用中,则 Base
的HelpMeNow()
将被调用,Derived
的实现将不可访问。
Derived derivedReference = new Derived();
Base baseReference = derivedReference;
IHelper helperReference = derivedReference;
derivedReference.HelpMeNow(); // outputs "Derived.HelpMeNow()"
baseReference.HelpMeNow(); // outputs "Base.HelpMeNow()"
helperReference.HelpMeNow(); // outputs "Base.HelpMeNow()"
当然,如果以上不是您想要的行为(通常情况下并非如此),则有两种可能性。如果您控制 Base
,只需将 HelpMeNow()
更改为 virtual,并在 Derived
中覆盖它而不是隐藏它。如果您不控制 Base
,那么您至少可以通过重新实现 IHelper
来中途修复它,如下所示:
class Derived : Base, IHelper{
public new void HelpMeNow(){Console.WriteLine("Derived.HelpMeNow()");}
void IHelper.HelpMeNow(){HelpMeNow();}
}
此版本的 Derived
使用所谓的显式接口(interface)实现,它允许您满足实现接口(interface)的约定,而无需将实现添加到类的公共(public)接口(interface)中。在此示例中,我们已经在 Derived
的公共(public)接口(interface)中实现了继承自 Base
的实现,因此我们必须显式实现 IHelper
才能更改它2。在这个例子中,我们只是将 IHelper.HelpMeNow
的实现转发给我们的公共(public)接口(interface),它是 Base
的影子。
因此,通过此更改,对 baseReference.HelpMeNow()
的调用仍会输出“Base.HelpMeNow()”,但对 helperReference.HelpMeNow()
的调用将现在输出“Derived.HelpMeNow()”。不如将 Base
的实现更改为虚拟的那么好,但如果我们不控制 Base
的话,我们将获得的效果也一样好。
1异常:它是可从 Derived
的方法中访问,但仅当使用 限定时base.
,如 base.HelpMeNow()
.
2请注意,我们还必须将 IHelper
声明为类实现的接口(interface),即使我们从 Base
继承此声明>.
关于c# - c# 接口(interface)中的新词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1338210/