C# 为什么Java或C中不允许多重继承?
我知道Java和C中不允许多重继承。很多书只是说,多重继承是不允许的。但它可以通过使用接口来实现。没有讨论为什么不允许这样做。有人能确切地告诉我为什么不允许使用MI吗?人们避开MI的主要(尽管不是唯一)原因是所谓的“钻石问题”,导致您的实现不明确。这篇文章对它进行了讨论,并比我所能解释的更好。MI还可能导致更复杂的代码,许多OO设计师声称您不需要MI,如果您使用它,您的模型可能是错误的。我不确定我是否同意最后一点,但保持简单始终是一个好计划。实现的多重继承是不允许的 问题是,如果您有一个Cowboy和一个Artist类,这两个类都有draw()方法的实现,然后您尝试创建一个新的CowboyArtist类型,编译器/运行时无法确定该怎么办。调用draw()方法时会发生什么?是有人死在街上,还是你有一幅可爱的水彩画C# 为什么Java或C中不允许多重继承?,c#,java,language-design,multiple-inheritance,C#,Java,Language Design,Multiple Inheritance,我知道Java和C中不允许多重继承。很多书只是说,多重继承是不允许的。但它可以通过使用接口来实现。没有讨论为什么不允许这样做。有人能确切地告诉我为什么不允许使用MI吗?人们避开MI的主要(尽管不是唯一)原因是所谓的“钻石问题”,导致您的实现不明确。这篇文章对它进行了讨论,并比我所能解释的更好。MI还可能导致更复杂的代码,许多OO设计师声称您不需要MI,如果您使用它,您的模型可能是错误的。我不确定我是否同意最后一点,但保持简单始终是一个好计划。实现的多重继承是不允许的 问题是,如果您有一个Cowb
我相信这就是所谓的双钻石继承问题。简单的回答是:因为语言设计者决定不这样做 基本上,.NET和Java设计人员似乎都不允许多重继承,因为他们认为添加MI会给语言增加太多的复杂性,而提供的好处太少 为了更有趣和更深入的阅读,在网上有一些关于一些语言设计师访谈的文章。例如,对于.NET,Chris Brumme(在微软的CLR上工作)解释了他们决定不这样做的原因:
< C++ >多重继承是使用不当时的一大头痛。为了避免这些流行的设计问题,现代语言(java,C#)强制多接口“继承”。另一个原因是单一继承使强制转换变得微不足道,不会发出汇编指令(除了检查所需类型的兼容性之外)。如果您有多重继承,那么您需要找出某个父类在子类中的起始位置。因此,性能当然是一种额外福利(虽然不是唯一的)。回到旧时代('70年代),当计算机科学更科学,批量生产更少时,程序员有时间考虑好的设计和良好的实施,因此产品(程序)具有高质量(例如TCP/IP设计和实施)。 如今,当每个人都在编程,管理者在截止日期前更改规格时,像Steve Haigh post在维基百科链接中描述的微妙问题很难追踪;因此,“多重继承”受到编译器设计的限制。如果你喜欢它,你仍然可以使用C++…并且拥有你想要的所有自由:)我对“Java中不允许多重继承”的说法持保留态度
当一个“类型”从多个“类型”继承时,就定义了多重继承。接口也可以根据其行为分类为类型。所以Java确实有多重继承。只是它更安全。多重继承更安全
- 难懂
- 很难调试(例如,如果您将多个框架中的类混合在一起,这些框架的深层方法具有相同的名称,那么可能会产生意想不到的协同效应)
- 易误用
- 不是很有用
- 很难实现,特别是如果您希望正确高效地完成
因此,不在Java语言中包含多重继承被认为是明智的选择。因为Java有着巨大的
public class A
{
void display()
{
System.out.println("Hello 'A' ");
}
}
public class B
{
void display()
{
System.out.println("Hello 'B' ");
}
}
public class C extends A, B // which is not possible in java
{
public static void main(String args[])
{
C object = new C();
object.display(); // Here there is confusion,which display() to call, method from A class or B class
}
}
interface A
{
// display()
}
interface B
{
//display()
}
class C implements A,B
{
//main()
C object = new C();
(A)object.display(); // call A's display
(B)object.display(); //call B's display
}
}
Class Shape1
{
public void CalculateArea()
{
//
}
}
Class Shape2
{
public void CalculateArea()
{
}
}
public class Circle: Shape1, Shape2
{
}
class A {
protected:
bool flag;
};
class B : public A {};
class C : public A {};
class D : public B, public C {
public:
void setFlag( bool nflag ){
flag = nflag; // ambiguous
}
};
B::flag = nflag;