这可能是一个愚蠢的问题,但我正在学习,我只是好奇发生了什么,今天我正在玩几个oops概念并在VS中学习它。我再次感到困惑的是,我们不必在派生类中实现多个接口相同的方法,其中ACTUALLY我们“继承”接口,但是在基类中。
我可以知道它是如何工作的吗?我担心的是,即使我没有在基类中“继承”接口方法,我也使用同名的方法。我也没有在派生类中实现它。
有人可以帮我理解发生了什么以及如何以及为什么?
Class A
{
public void Display()
{
Console.Writeline("I am from A");
}
}
interface IA
{
void Display();
}
interface IB
{
void Display();
}
Class B : A, IA, IB
{
}
Class Final
{
static void Main()
{
B b = new B();
b.Display(); // displays class A Display method.
Console.Readline();
}
}
答案 0 :(得分:3)
原因是因为实现是“隐含的” - 接口的隐式实现。
Class A
{
public void Display()
{
Console.Writeline("I am from A");
}
}
interface IA
{
void Display();
}
interface IB
{
void Display();
}
Class B : A, IA, IB
{
void AI.Display() { Console.Writeline("I am from AI.Display"); }
}
Class Final
{
static void Main()
{
B b = new B();
b.Display(); // displays class A Display method.
(b as IB).Display(); // displays class A Display method.
(b as AI).Display(); // displays AI.Display
Console.Readline();
}
}
上面的示例现在具有接口方法显示的显式实现。请注意方法签名的轻微变化 - 这是您声明显式实现的方式,该实现在接口表示对象时特别使用,在本例中为(b as AI)
。
否则,如果方法签名匹配,则自动(隐式)使用它作为接口的方法。
答案 1 :(得分:3)
虽然我不能代表语言团队发言,但您可以通过提出替代解决方案来回答这个问题。
您想知道为什么B
被认为是实现接口IA
,即使所需的方法定义在基类A
中,也没有实现接口。所以,让我们考虑相反的情况:B
这意味着您的代码无法编译。为什么不编译?由于B
未实现接口Display
所需的成员IA
。
要解决此问题,您需要向类Display
添加方法B
。这修复了接口实现。但是,您现在遇到了一个新的编译问题:您将看到警告“B.Display()”隐藏继承的成员'ConsoleApplication1.A.Display()'。如果想要隐藏,请使用new关键字。“
这是因为您的A.Display
无法覆盖 - 而且您不想覆盖它。如果你选择的话,你可以实现一个方法来调用base.Display()
,但是这是额外的代码,基本上什么都不做,并且它使你的继承变得混乱,因为new
方法的处理方式不同于覆盖。 (如果您编写A x = new B(); x.Display();
,那么您实际上会直接调用A.Display()
,这可能会因您的代码发展而变得混乱,并且等待发生事故。)
或者,您可以实现一个全新的B.Display
方法。您现在所做的是隐藏在A
类中实现的方法,可能来自可能派生自B
或创建B
实例的任何人。使用new
隐藏方法很少是可理解的对象结构的一个配方,这也不例外 - 所有这些都可以让你干净地实现一个接口。
所以最终,我想,这个决定是因为替代方案过于混乱。
答案 2 :(得分:1)
在你的情况下发生的事情是,B类通过继承A类适当的IA方法实现这一事实来满足IA接口契约。
答案 3 :(得分:1)
查看它的方法是 - 接口是契约(它没有实现)因此它只是要求任何实现类定义它在契约中定义的所有相同成员。
在您的情况下,您的界面Display
中有1个方法,您的类B
是实现此界面的唯一类,并且显式未定义实现Display
(也许这就是你的困惑所在)。但是,它继承自A
为其定义实现,因此B
默认实现接口。