在The C# Programming Language Krzysztof Cwalina中注释:
我们明确决定不添加对多重继承的支持 [...]缺乏多重继承迫使我们添加概念 接口,反过来又导致问题 框架的演变,更深层次的继承层次结构,以及许多 其他问题。
接口是面向对象编程语言的核心概念。我没有遵循“强迫我们添加接口的概念”的含义
Krzysztof是否意味着必须就接口的使用作出某些设计决策,否则将使用多重继承?或者,他是否因为缺少多重继承而将interface
引入C#?你能提供一个例子吗?
答案 0 :(得分:24)
接口只是一个没有数据成员且只定义public abstract
方法的基类。例如,这将是C ++中的一个接口:
class IFrobbable {
public:
virtual void Frob() = 0;
}
因此,当MI可用作语言功能时,您可以通过简单地从它们派生来“实现”接口(再次,C ++):
class Widget : public IFrobbable, public IBrappable {
// ...
}
一般情况下的多重继承 会产生许多问题和问题,这些问题和问题不一定只有一个答案,或者甚至是您对“好”的特定定义的好问题({{3 }}, 任何人?)。多接口实现完全避免了大部分这些问题,因为“继承”接口的概念是继承完整类的一个非常有限的特殊情况。
这就是“迫使我们添加接口概念”的地方:在仅限于单一继承时,你不能做很多OO设计,例如,当代码重用时,无法重用代码存在严重问题事实上,OO最常见的一个论点。您必须做更多的事情,下一步是添加多继承,但仅适用于满足接口约束的类。
所以,我将Krzysztof的引言解释为
一般情况下的多重继承是一个非常棘手的问题 在现实生活中,我们无法以令人满意的方式解决问题 对.NET开发的限制。但是,接口继承 两者都很多 在OOP中更容易解决并且至关重要,因此我们确实如此 但是当然接口也有自己的问题, 主要是关于BCL的结构。
答案 1 :(得分:11)
来自Chris Brumme:
有很多原因我们没有实现Multiple 直接实现继承。 (如您所知,我们支持多个 接口继承)。
我认为Krzysztof Cwalina在引用中所说的不是接口本身的概念,而是多接口继承作为多重继承的方法。
我们有几个原因没有提供可验证的,可验证的, 符合CLS的多实现继承版本:
不同的语言实际上对MI的工作方式有不同的期望。例如,如何解决冲突以及是否重复 基地合并或冗余。在我们在CLR中实现MI之前, 我们必须对所有语言进行调查,找出共同点 概念,并决定如何以语言中立的方式表达它们。 我们还必须决定MI是否属于CLS以及什么 这对于不想要这个概念的语言来说意味着(大概是这样) 例如VB.NET)。当然,这就是我们所处的业务 公共语言运行时,但我们还没有为MI做这件事 爱好。
MI真正适合的地方实际上非常小。在许多情况下,多个接口继承可以获得 完成工作。在其他情况下,您可以使用封装 和代表团。如果我们要添加一个稍微不同的结构,比如 mixins,实际上会更强大吗?
- 醇>
多个实现继承为实现注入了很多复杂性。这种复杂性影响了铸造,布局, 调度,现场访问,序列化,身份比较, 可验证性,反思,泛型,可能还有很多其他的 地方。
答案 2 :(得分:4)
我认为你应该read what Eric Lippert says about Interfaces
。他的手很脏,所以我觉得他比其他人都清楚。
有时会出现更严重的情况和最严重的情况。你必须选择不那么糟糕的人。
以下是链接帖子的副本:
他们只是为了确保所述功能(在...中) 接口)在继承类中实现。
正确。这是证明该功能合理性的一个非常好的好处。正如其他人所说,界面是实现某些方法,属性和事件的合同义务。静态类型语言的令人信服的好处是编译器可以验证您的代码所依赖的合同是否真正得到满足。
尽管如此,界面是代表合同义务的一种相当薄弱的方式。如果您想要更强大,更灵活的方式来表示合同义务,请查看最新版本的Visual Studio附带的“代码合同”功能。
C#是一种很棒的语言,但有时会给你一种感觉 首先Microsoft创建问题(不允许多个 继承)然后提供解决方案,而不是一个 乏味的。
我很高兴你喜欢它。
所有复杂的软件设计都是权衡相互冲突的功能,并试图找到“甜蜜点”,为小成本带来巨大好处。我们通过痛苦的经验了解到,为实现共享目的而允许多重继承的语言具有相对较小的优势和相对较高的成本。仅允许在不共享实现细节的接口上进行多重继承,可以提供多重继承的许多好处,而无需大部分成本。
答案 3 :(得分:2)
我认为Cwalina的语言有点强,而且对于历史并不完全准确。
请记住,在C#之前接口已经存在,所以说“我们必须添加接口以解决问题x”对我来说听起来不对。我认为接口默认存在 - 它们必须是。
另外,请记住C#主要来自C ++。或者,至少,参与创建C#语言的人员在C ++中具有非常强的背景。多重继承是C ++中公认的噩梦区。继承自多个类,这些类本身可以从commonm基类派生,确定哪个实现优先等等。我的意思是,它是一个非常强大的功能,但无疑会导致复杂的代码。
我怀疑他们从C#中删除了多重继承,因为他们(语言作者)知道一切都会变得纠结,他们想避免这种情况。还要记住,当引入C#时,它的一个卖点就是它的清洁度(没有比Java更清洁,但比C和C ++更清洁)。
顺便说一句,在10多年的C#开发中,我只希望一次多重继承。我想要继承视觉样式和一些常见行为的UI组件。我花了很长时间才意识到我打算做的事情在任何情况下都是一个非常糟糕的设计。