我了解到C#不支持多重继承,解决方案是使用接口代替。但我不明白的是,为什么接口不会像多重继承那样产生菱形问题。使用接口如何避免多重继承的陷阱?
一个类可以 implement 任意数量的接口,即使这些接口也扩展了其他接口。多重inheritance仅在classes中是不可能的。
// This is not allowed
class A { void A() {} }
class B { void B() {} }
class C : A, B {}
// This is allowed
interface IA { void A(); }
interface IB { void B(); }
class A : IA, IB
{
public void A() {}
public void B() {}
}
菱形问题存在于类中,因为存在实现冲突的可能性(如果
A
和B
有相同的方法并且C
扩展了两者,它采用哪种方法?)。另一方面,接口只需要一个实现类型来拥有它们声明的方法。
如果在两个接口中定义了完全相同的方法,并且一个类实现了这两个接口,那没关系。该类需要做的就是为该方法提供一个实现,以便可以编写代码来调用该方法。意思是,这有效:
interface IA { void Method(int x); }
interface IB { void Method(int x); }
class A : IA, IB
{
public void Method(int x)
{
Console.WriteLine(x);
}
}
注意一个类可能仍然继承自另一个类,加上任意数量的接口:
class A : B, IA, IB {}
仅使用接口时不存在“钻石问题”,因为不可能有歧义的实现。阅读维基百科文章,其中包含完整的解释。
多个接口不会产生钻石问题,因为每个类都必须提供自己的unique实现,这意味着没有资源共享。
C# 不允许多重继承,因为他们关心你,并使语言尽可能地防止自己出事。
我认为仅在
C#
的范围内考虑这个是不公平的。
CLR
本身不支持多重继承。可能是因为他们想支持其他目前不支持或将来不支持的语言。
一次只能继承一个类和任意数量的接口
如果问继承:类只能继承一个类,但可以实现任意多个接口。请参阅这篇关于 C# 中的继承和多态性的文章。
这是一种尝试实现通常可以通过多重继承实现的东西的可能方法。
interface IA
{
void DoAnything(string name);
}
class A : IA
{
public void DoSomething()
{
// some code
}
public void DoAnything(string name)
{
// Some code
}
}
class B : IA
{
public void DoNothing()
{
// Some code
}
public void DoAnything(string name)
{
// Some code
}
}
class StorageCache : IA
{
private A ObjA;
private B ObjB;
public void DoAnything(string name)
{
ObjA.DoAnything(name);
ObjB.DoAnything(name);
}
public void DoNothing()
{
ObjB.DoNothing();
}
public void DoSomething()
{
ObjA.DoSomething();
}
}