C# 缺乏多重继承如何导致对接口的需求?
本文关键字:接口 需求 何导致 多重继承 | 更新日期: 2023-09-27 17:55:48
在C#编程语言中,Krzysztof Cwalina在注释中指出:
我们明确决定不添加对多重继承的支持 [...]缺乏多重继承迫使我们添加概念 接口,而接口又是导致 框架的演变、更深层次的继承层次结构以及许多 其他问题。
接口是面向对象编程语言的核心概念。 我不遵循"强迫我们添加接口概念"的含义
Krzysztof 是否意味着必须就接口的使用做出某些设计决策,否则将使用多重继承? 或者,他的意思是interface
被引入C#是因为缺乏多重继承?你能举个例子吗?
接口只是一个基类,它没有数据成员,只定义public abstract
方法。例如,这将是C++中的一个接口:
class IFrobbable {
public:
virtual void Frob() = 0;
}
因此,当 MI 作为语言功能可用时,您可以通过简单地从接口派生来"实现"接口(再次,C++):
class Widget : public IFrobbable, public IBrappable {
// ...
}
在一般情况下,多重继承会产生许多问题和问题,这些问题和问题不一定有一个单一的答案,甚至不一定有一个好的答案,对于你对"好"的特定定义(可怕的钻石,有人吗?)。多接口实现回避了这些问题中的大多数,正是因为"继承"接口的概念是继承成熟类的非常受约束的特殊情况。
这就是"迫使我们添加接口概念"的用武之地:当仅限于单个继承时,您无法进行太多的OO设计,例如,当代码重用实际上是OO最常见的参数之一时,无法重用代码存在严重的问题。您必须做更多的事情,下一步是添加多重继承,但仅适用于满足接口约束的类。
所以,我将克日什托夫的引述解释为:
在一般情况下,多重继承是一个非常棘手的问题, 鉴于现实生活,我们无法以令人满意的方式解决 对 .NET 开发的约束。但是,接口继承 既多 在 OOP 中更容易处理并且具有至高无上的重要性,所以我们确实把它放在了 在。但当然,接口也有自己的一系列问题, 主要是关于BCL的结构。
来自 Chris Brumme:
我们不实施多个的原因有很多 直接实现继承。(如您所知,我们支持多个 接口继承)。
我认为 Krzysztof Cwalina 在引文中所说的不是接口本身的概念,而是作为多重继承方法的多接口继承
。我们没有提供内置的、可验证的、 符合 CLS 的多重实现继承版本:
不同的语言实际上对MI的工作方式有不同的期望。例如,如何解决冲突以及是否重复 碱基是合并的或冗余的。在 CLR 中实现 MI 之前, 我们必须对所有语言进行调查,找出共同点 概念,并决定如何以语言中立的方式表达它们。 我们还必须决定 MI 是否属于 CLS 以及什么 这意味着对于不想要这个概念的语言(大概 VB.NET 例如)。当然,这就是我们作为业务的业务 公共语言运行时,但我们还没有为MI做这件事 还。
MI真正合适的地方数量实际上很少。在许多情况下,多接口继承可以获得 相反,工作已完成。在其他情况下,您可以使用封装 和授权。如果我们要添加一个稍微不同的结构,例如 混音,那真的会更强大吗?
多实现继承给实现注入了很多复杂性。这种复杂性会影响铸造、布局、 调度、字段访问、序列化、身份比较、 可验证性、反射、泛型,可能还有许多其他 地方。
我认为你应该阅读埃里克·利珀特(Eric Lippert)对Interfaces
的评价。他的手很脏,所以我认为他比其他人都清楚。
有时有更糟糕的情况和最坏的情况。你必须选择不那么糟糕的。
以下是链接帖子的副本:
他们在那里只是为了确保所述功能(在 接口)在继承类中实现。
正确。这是一个足够棒的好处来证明该功能的合理性。正如其他人所说,接口是实现某些方法、属性和事件的合同义务。静态类型语言的引人注目的好处是,编译器可以验证代码所依赖的协定是否实际得到满足。
也就是说,接口是表示合同义务的一种相当弱的方式。如果你想要一种更强大、更灵活的方式来表示合同义务,请查看上一版 Visual Studio 附带的代码协定功能。
C# 是一种很棒的语言,但有时它会给你一种感觉 首先Microsoft会产生问题(不允许多个 继承),然后提供解决方案,这是一个 乏味的一个。
好吧,我很高兴你喜欢它。
所有复杂的软件设计都是权衡相互冲突的功能的结果,并试图找到以小成本带来巨大收益的"最佳点"。我们从痛苦的经验中了解到,允许为实现共享目的进行多重继承的语言具有相对较小的收益和相对较大的成本。只允许在不共享实现细节的接口上进行多重继承,这提供了多重继承的许多好处,而没有大部分成本。
我认为Cwalina的语言有点强,而且对历史并不完全准确。
请记住,接口在 C# 之前就已经存在,所以说"我们必须添加接口来解决问题 x"对我来说听起来不对。我认为默认情况下接口会在那里 - 它们必须在那里。
另外,请记住,C# 主要派生自 C++。或者,至少,参与创建 C# 语言的人员在C++方面具有非常强大的背景。多重继承是C++公认的噩梦领域。从多个类继承,这些类本身可能派生自 commonm 基类,确定哪个实现优先等。我的意思是,这是一个非常强大的功能,但无疑会导致复杂的代码。
我怀疑他们放弃了 C# 的多重继承,因为他们(语言作者)知道一切会变得多么纠结,他们想避免这种情况。还要记住,当引入 C# 时,它的卖点之一是它的清洁度(公平地说,没有比 Java 更干净,但比 C 和 C++ 干净得多)。
顺便说一下,在 10+ 年的 C# 开发中,我只希望多次继承一次。一个UI组件,我想继承视觉风格和一些常见行为。没过多久,我就意识到我打算做的无论如何都会是一个非常糟糕的设计。