c# - c# 接口(interface)中的新词

标签 c# interface

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 对象的引用,BaseHelpMeNow 函数将不可访问1,并且 derivedObject.HelpMeNow() 将调用 Derived 的实现。

这与覆盖虚函数不同,HelpMeNow 不是。如果 Derived 对象存储在对 BaseIHelper 的引用中,则 BaseHelpMeNow() 将被调用,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/

相关文章:

c# - 什么是IBuffer?

c# - 如何避免 NullReferenceException

c# - 从给定的字体名称获取字体文件

多个类的 C# 接口(interface)

android - 如何在fragment中实例化接口(interface)?

c++ - 在抽象层次结构的具体实例上执行契约

java - 需要通过java代码将.json文件插入MongoDB

c# - .NET 将字符串转换为句子大小写的方法

java - 引用类型和对象类型之间的区别?

java - 实现接口(interface)和继承