3

这可能是一个愚蠢的问题,但我正在学习,我只是好奇发生了什么,今天我正在玩一些 oops 概念并在 VS 中学习它。我再次感到困惑的是,我们不必在派生类中实现多个接口相同的方法,实际上我们“继承”了接口,而是在基类中。

我可以知道它是如何工作的吗?我担心的是,即使我没有在基类中“继承”接口方法,我也会使用同名的方法。我也没有在派生类中实现它。

有人可以帮助我了解发生了什么以及如何以及为什么?

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();
    }
}
4

4 回答 4

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();
 }
}

上面的例子现在有了接口方法 display 的显式实现。请注意方法签名中的细微变化——这是您声明显式实现的方式,在这种情况下,当对象由接口表示时专门使用它(b as AI)

否则,如果方法签名匹配,它会自动(隐式)用作接口的方法。

于 2013-11-11T15:52:49.107 回答
3

虽然我不能代表语言团队发言,但您可以通过提出替代解决方案来回答这个问题。

您想知道为什么B要考虑实现接口IA,即使所需的方法定义在A未实现接口的基类中。因此,让我们考虑相反的情况:B应该考虑实现接口,因为基类的方法没有考虑到该接口。

这意味着您的代码无法编译。为什么不编译?因为B没有实现Displayinterface 的必需成员IA

要解决此问题,您需要Display向 class添加一个方法B。这修复了接口实现。但是,您现在遇到了一个新的编译问题:您将看到警告“B.Display()' hides继承的成员'ConsoleApplication1.A.Display()'。如果要隐藏,请使用新关键字。”

这是因为您A.Display的不可覆盖 - 而且您不想覆盖它。如果你愿意,你可以实现一个方法来调用base.Display(),但这是额外的代码,基本上什么都不做,而且它会弄乱你的继承,因为new方法的处理方式与覆盖不同。(如果您编写A x = new B(); x.Display();,那么您实际上会A.Display()直接调用,随着代码的发展,这可能会变得混乱,并且是等待发生的事故。)

或者,您可以实现一个全新的B.Display方法。您现在所做的还是将在类中实现的方法对任何A可能从. 使用隐藏方法很少是一个可理解的对象结构的秘诀,这也不例外——所有这些都是为了你可以干净地实现一个接口。BBnew

所以最终,我想,做出这个决定是因为替代方案太混乱了。

于 2013-11-11T16:02:51.207 回答
1

看待它的方式是这样的——接口是一个契约(它没有实现),因此它只要求任何实现类定义它在契约中定义的所有相同成员。

在您的情况下,您的 interface 中有 1 个方法Display,您的类B是唯一实现此接口的类,并且它没有明确定义实现Display(也许这是您的困惑所在)。但是,它继承了A确实为它定义了一个实现,因此B默认情况下实现了该接口。

于 2013-11-11T15:57:04.957 回答
1

在您的情况下发生的情况是,B 类通过从 A 类继承适当的 IA 方法实现这一事实来满足 IA 接口契约。

于 2013-11-11T15:55:03.783 回答