gpt4 book ai didi

c# - 实现接口(interface)的抽象基类

转载 作者:IT王子 更新时间:2023-10-29 04:23:41 25 4
gpt4 key购买 nike

假设我有一个简单的抽象基类

abstract class Item : IDisplayable
{
public int Id { get; set; }
public string Name { get; set; }
public abstract void Print();

}

我有一个继承自它的类

  class Chair: Item
{
public int NumberOfLegs {get;set;}

public void Print()
{
Console.WriteLine("Here is a simple interface implementation");
}
}

interface IDisplayable
{
void Print();
}

子类没有明确表示它也实现了接口(interface),但它会通过简单的继承来实现。如果我们显式地将接口(interface)添加到子类,程序将以相同的方式运行(至少就我在简单示例中所知道的而言)。显式实现接口(interface)是好是坏,还是严格意义上的偏好问题?

最佳答案

If we explicitly add the Interface to the child classes the program will run the same (at least as far as I can tell in my simple examples).

程序运行起来不一定一样;您的示例不足以说明差异。

Would explicitly implementing the interface be a good or bad idea, or is it strictly a matter of preference?

除非您打算确保接口(interface)重新实现语义,否则这是个坏主意。

让我简单说明一下。这个程序是做什么的?

using System;
interface IFoo { void Bar(); void Baz(); }
class Alpha : IFoo
{
void IFoo.Bar()
{
Console.WriteLine("Alpha.Bar");
}
void IFoo.Baz()
{
Console.WriteLine("Alpha.Baz");
}
}
class Bravo : Alpha
{
public void Baz()
{
Console.WriteLine("Bravo.Baz");
}
}
class CharlieOne : Bravo
{
public void Bar()
{
Console.WriteLine("CharlieOne.Bar");
}
}
class CharlieTwo : Bravo, IFoo
{
public void Bar()
{
Console.WriteLine("CharlieTwo.Bar");
}
}
class Program
{
static void Main()
{
IFoo foo = new Alpha();
foo.Bar();
foo.Baz();
foo = new Bravo();
foo.Bar();
foo.Baz();
foo = new CharlieOne();
foo.Bar();
foo.Baz();
foo = new CharlieTwo();
foo.Bar();
foo.Baz();
}
}

在继续阅读之前,认真地:尝试预测这个程序的输出

现在实际运行它。 您是否获得了预期的输出?您的直觉哪里错了?

现在你看出 CharlieOneCharlieTwo 之间的区别了吗? CharlieTwo 中重新实现 IFoo 会导致接口(interface)绑定(bind)获取 Bravo.Baz,即使 Bravo 重新实现IFoo!

另一方面:如果您期望 Bravo.Baz 仅仅因为它存在就被分配给接口(interface)槽,那么您会看到如何失败重新实现接口(interface)导致代码不正确。要让 Bravo.Baz 替换 Alpha.IFoo.BazBravo 必须重新实现 IFoo

这里的要点是:当您重新实现一个接口(interface)时,所有接口(interface)绑定(bind)都会从头开始重新计算。这会导致语义程序发生变化,因此只有在您打算这样做时才重新实现接口(interface)

这也说明了另一种形式的脆弱的基类失败。假设 Bravo 在编写 Charlie 时没有方法 Baz。如果您编写 Charlie 来重新实现 IFoo,那么 Bravo 的作者会添加 Baz 之后 -- Bravo 的作者可能在贵公司的不同团队中 -- 更改 Charlie 中的接口(interface)绑定(bind),即使这不是 的作者所做的>Bravo 意图。

有关更多信息,请参阅我关于该主题的文章:

http://blogs.msdn.com/b/ericlippert/archive/2011/12/08/so-many-interfaces-part-two.aspx

关于c# - 实现接口(interface)的抽象基类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17278333/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com