This question already has an answer here:
base class implementing base interface while derived/concrete class implementing extended interface, why?
(1个答案)
1年前关闭。
为什么该程序打印“子名称”而不是“基本名称”?
我希望当我将子类型转换为INamedObject时,将调用INamedObject显式实现的Name属性。但是会发生什么,就是调用了Child.Name属性。
为什么当我这样声明Child类时(从Child中删除INamedObject):
它开始打印“基本名称”?
(1个答案)
1年前关闭。
为什么该程序打印“子名称”而不是“基本名称”?
using System;
class Program
{
static void Main(string[] args)
{
var child = new Child();
Console.WriteLine(((INamedObject)child).Name);
Console.ReadLine();
}
}
interface INamedObject
{
string Name { get; }
}
class Base : INamedObject
{
string INamedObject.Name
{
get
{
return "Base Name";
}
}
}
class Child : Base, INamedObject
{
public string Name
{
get
{
return "Child Name";
}
}
}
我希望当我将子类型转换为INamedObject时,将调用INamedObject显式实现的Name属性。但是会发生什么,就是调用了Child.Name属性。
为什么当我这样声明Child类时(从Child中删除INamedObject):
class Child : Base
{
public string Name
{
get
{
return "Child Name";
}
}
}
它开始打印“基本名称”?
最佳答案
其他答案不能正确识别您偶然发现的C#功能。
您已经发现了C#的一个令人困惑的功能,称为“接口(interface)重新实现”。规则是,当派生类专门重新声明已经由基类实现的接口(interface)时,编译器将重新开始并重新进行接口(interface)映射。
如果发生这种情况,则派生类型更多的方法将优先于派生类型较少的方法,因为我们认为开发更多派生类型的开发人员比开发基类版本的开发人员具有更好的实现。毕竟,如果派生版本较差,开发人员将不会实现它!
该规则使您可以决定是否要派生类替换基类接口(interface)映射,因为有时您想要,有时不想要。
有关更多详细信息,请参阅我在2011年发表的有关此功能的文章:
https://blogs.msdn.microsoft.com/ericlippert/2011/12/08/so-many-interfaces-part-two/
您可能还会发现此答案有帮助:
Abstract base classes that implement an interface
有关描述此语言功能的规范部分,请参见
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/interfaces#interface-re-implementation