为什么接口的多重继承比一组类的多重继承要难得多? 我被困在一个大学问题上。 感谢
答案 0 :(得分:3)
如果从不同的类继承具有相同签名的两个方法,则在调用此方法时会有歧义。它可以解决,但它可以说是一个混乱的情况。
如果使用相同的方法签名实现两个接口,则无关紧要,因为在调用方法时仍然只有一个实现可供选择。
The diamond problem是上述问题的延伸,这使得情况更加混乱。当将多重继承限制为接口时,这个问题基本消失了。
答案 1 :(得分:0)
也许是因为粒度:你可以选择你的类应该实现哪些接口。而如果扩展类,则会自动继承类的整个层次结构。
答案 2 :(得分:0)
两个可能的原因: 1.)钻石问题(在维基百科中查看), 2.)对象身份。
class A { }
class B { }
class C : A, B { }
C * c = new C ();
A * a = c;
B * b = c;
然后,您无法通过简单地测试== b来验证对象标识。如果您尝试在某种语言中实现此功能,则不能在后台使用简单的指针算法,这样每个对类的访问(独立于多重继承)会变得更加昂贵,因为a和b不再是普通的指针了。
如果A和B是接口,您就知道问题(您知道它们将被继承),这样您就可以区别对接入类的访问来处理对接口的访问。
顺便说一句:多类继承不是 难以实现的。
编辑:添加。它引入了概念性问题:
class C0 { virtual int meth { return 0; } };
class C1 : C0 { virtual int meth { return 1; } };
class C2 : C1, C0 { }
如果我们定义
C2 * c2 = new C2;
应该是什么
((C1 *) c2)->meth()
和
((C0 *) c2)->meth()
为了不让人迷惑而返回? (编辑:更正了此示例。)
答案 3 :(得分:0)
至少在.net中指出,接口方法仅适用于被声明为接口类型或受其约束的对象。因此,如果C1
具有方法Foo
,并且还实现了接口Intf1
和Intf2
,每个接口都声明了方法Foo
,那么在大多数情况下事实上存在三个名为Foo
的方法并不重要,因为它们将存在于基本上独立的域中。
此外,如果接口IDerived1
和IDerived2
继承IBase
,其中包含成员Foo
,实现这两个接口的类,或继承两个接口的接口,将只定义IBase.Foo
的一个定义。 IDerived1
,IDerived2
和/或从两者派生的接口都可以声明自己的Foo
成员,但任何此类定义都与IBase.Foo
完全分开。将派生接口转换为IBase
并在其上调用Foo
将始终产生相同的IBase.Foo
方法,无论是直接转换为IBase
还是转换为其他接口第一。相反,如果一个类派生自另外两个类,这两个类都覆盖了公共基类的相同成员,那么如果将派生类的对象强制转换为基类然后尝试使用该成员,则不清楚会发生什么
顺便说一下,有一些情况会出现歧义。如果一个接口继承了两个具有相同名称成员的接口,则可能需要使用一些技巧来强制编译器优先于另一个,或者让派生接口添加自己的同名成员,这将成为阴影两个原件。此外,在使用泛型时,可以约束泛型类型以实现多个接口,并且还可以从类继承。完成此操作后,如果接口和/或类共享成员名称,则可能存在歧义。