最近,在阅读了“编程语言与实践”一书中的一些文章后,提到Java中的多个接口继承不会遇到与C ++中多类继承相同的问题。
但我无法理解为什么会这样。在C ++实现错误中,java如何能够使用多个接口继承?
有没有办法在C ++中替换多继承以避免实现问题?
对于最后一个更具体的陈述,我们可以说:
class A {...};
class B : public A {...};
class C : public A {...};
class D : public B, public C {...};
然后D类继承继承A类的B类,C类。因此,如果A有一个字段变量,那么B,C将具有相同的变量名,然后是D具有的变量(继承自B或C)。为了避免这种情况,我们可以编写上面的代码而没有多重继承,但结果相似吗?
这个问题不是重复的,因为它没有关注最终将是示例中的继承,而是要了解Java-C ++多重继承之间的区别(参见上面的第一个问题)以及是否有方法建议克服一些多重继承问题(如上所述)。
答案 0 :(得分:4)
Java(与C ++不同)不允许州的multiple inheritance,因此不会受到diamond problem的影响。
它允许通过接口多次继承类型(一个类可以实现多个接口)。
从Java 8开始,接口中还有行为到default
方法的多重继承。
答案 1 :(得分:3)
但我无法理解为什么会这样。当C ++实现错误存在时,java如何能够使用多个接口继承?
这是可能的,因为 Java 不允许多重继承,但只允许来自多个接口的多个实现。
实施与继承不同。
多重继承的一般问题是( in shor t)两个类可以定义不同的做同样事情的方法,并且子类无法选择要选择哪一个。
由于 java 中的 interface 只能 声明方法的签名而不实现它们,如果派生了多个接口,则问题不存在。
总之,为了避免Java问题,禁止直接进行多重继承,并且只允许多次实现接口。
有没有办法在c ++中替换多继承以避免实现问题?
我能给你的第一个建议是避免设计如此复杂。
无论如何,您在问题中暴露的问题非常普遍,称为diamond problem。
C ++提供了一个解决方案,以便使用virtual inheritance
来解决这个问题。
设一个继承图:
A
/ \
B C
\ /
D
这是问题所在:
默认情况下,C ++分别跟随每个继承路径,因此
D
对象实际上包含两个单独的A
个对象,并且必须正确限定A&#39}成员的使用。
这是关于virtual
继承的简要说明:
如果从
A
到B
的继承以及从A
到C
的继承都标记为"虚拟" (例如,"class B : virtual public A
"),C ++特别注意仅创建一个A
对象,并使用A
& #39;成员工作正常。如果混合了虚拟继承和非虚拟继承,则每个到A
的非虚拟继承路径都有一个虚拟A和一个非虚拟A。
简而言之,使用virtual
继承,可以防止类A
中的部分类D
重复。
答案 2 :(得分:2)
为了避免这种情况,我们可以编写上面的代码而没有多重继承,但结果相似吗?
它遵循一个最小的工作示例:
uploadBtnText
如果您不想创建显式层次结构,但仍希望使用struct A {};
struct B {};
struct C {};
struct D {
operator A&() { return a; }
operator B&() { return b; }
operator C&() { return c; }
private:
A a;
B b;
C c;
};
void f(const B &b) {}
int main() {
D d;
f(d);
}
的实例,其中需要引用D
,则上述解决方案效果很好。<登记/>
正如您所看到的,它基于构图而不是继承
当然,它有一些限制,例如,你不能将B
的指针强加到指向D
的指针。
如果符合你的要求,主要取决于真正的问题,所以我不能说 无论如何,如果您有兴趣了解更多详细信息,那么这是一个与inner class idiom类似的可行解决方案。
答案 3 :(得分:0)
&#34;多重继承&#34;在Java中没有真正的多重继承。由于Java只能通过使用接口来创建钻石问题。
接口只是对子类中实现的方法的引用,因为接口无法实现方法。
因此,子类不能让父母具有不同的实现。由于不存在实现,因此从哪个接口继承该方法并不重要。
编辑:哦,我忘记了Java如何通过引入default
方法破坏了接口背后的原理......