为什么子类需要实现父接口来隐藏C#中的父类方法之一?

时间:2011-03-11 18:38:16

标签: c# inheritance interface

我在使用第三方库时发现了这种行为,我需要隐藏并更改其中一种方法。

我有以下设置:

interface IBaseInterface
{
    string MethodToHide();
}

class BaseClass : IBaseInterface
{
    public string MethodToHide()
    {
        return "BaseClass";
    }
}

class ChildClass : BaseClass
{
    new public string MethodToHide()
    {
        return "ChildClass";
    }
}

为什么当我运行以下内容时:

var i = (IBaseInterface) (new ChildClass());
Console.WriteLine(i.MethodToHide());

输出

  

BaseClass的

,但是将ChildClass签名更改为

class ChildClass : BaseClass, IBaseInterface

,输出

  

ChildClass

为什么我需要明确指定ChildClass隐藏的BaseClass方法的接口?

3 个答案:

答案 0 :(得分:4)

您需要详细了解覆盖隐藏之间的区别:

链接:Override versus Hide

简而言之:

隐藏(使用新的)根据变量的类型运行方法 覆盖会覆盖该方法,并且只会使用子方法。

修改

使用Interface变量时:

var i = (IBaseInterface) (new ChildClass());

编译器将搜索接口使用的方法的最佳匹配 因为您声明 BaseClass 来实现接口,所以将选择其方法。

如果 ChildClass 没有显式实现接口,则编译器无法将方法链接到接口。从它的角度来看, BaseClass 碰巧有相同名称的方法。

显式声明 ChildClass 也实现了接口时,其方法将是最佳选择。

答案 1 :(得分:2)

您需要在BaseClass中将MethodToHide标记为虚拟。然后你的ChildClass可以覆盖它。有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/9fkccyh4(v=vs.80).aspx

我相信这是规范的相关部分:

  

10.6.3虚拟方法在虚方法调用中,运行时类型   对此的实例   调用发生决定了   实际的方法实现   调用。在非虚方法中   调用,编译时类型   实例是决定因素   因素。

因此,当您将原始对象转换为IBaseInterface时。它确定类型是BaseClass,因为它是实现它并调用其方法的类型。在第二个示例中,它将其解析为ChildClass并调用其方法。

答案 2 :(得分:1)

因为main-class实现了接口。子类只定义了一个与接口无关的新方法。实际上,子类隐藏了该方法 - 这就是'新'所做的。