Java不允许多重继承,这意味着一个类不能从两个类继承,这两个类没有任何共同点,这意味着它们不在同一个继承路径上。但是,如果这些类是类的直接超类的超类,则类可以从更多类继承。但是这个类间接地从这些类继承,这意味着它不会从这些超级类中“看到”任何东西,对吧?在考虑构造函数时(在构造函数中使用super())我很困惑。例如,如果我们有以下类:
public class A {
public A() {
....
}
}
public class B extends A {
public B() {
super();
....
}
}
public class C extends B {
public C() {
super();
....
}
}
类C的构造函数首先使用super()调用类B的构造函数。当发生这种情况时,B本身的构造函数首先调用A的构造函数(带有super()),但是C的构造函数对A的构造函数一无所知,对吧?我的意思是,继承只来自直接超类 - 继承层次结构中的第一个(最近的)类。这是我的问题 - 使用super()我们只是指直接超类的构造函数,无论我们在继承层次结构中有多少其他类。 这不仅适用于构造函数,也适用于任何方法和实例变量。
此致
答案 0 :(得分:4)
您必须在直接基类中调用某些构造函数。这可以是
public class A {
public A() {
....
}
public A(String foo) {
....
}
}
public class B extends A {
public B() {
super();
.. or ..
super("ThisIsAB")
}
}
public class C extends B {
public C() {
super();
....
}
}
因此,对于构造函数,您无法AVOID构造中间基类,但您可以选择使用哪个构造函数。如果只有no-args构造函数,则会通过对super的隐式调用来处理它。使用多个构造函数,您可以有更多选择。
super可以引用任何基类中的任何非私有变量或方法。因此,方法和变量在这方面与构造函数不同。
答案 1 :(得分:4)
即使你可以避免调用中间ctor,你也不会想要,因为这意味着你有未初始化的中间类片段,这些片段可能被最底层的派生类所取代。对可怕的影响。
但是我觉得你正试图绕过Java去做多重继承。这是一件坏事。相反,您可以通过使用接口
来实现Javaclass B extends A implements C {
// ... implement C methods here
}
或使用聚合
class B extends A {
private C c;
}
答案 2 :(得分:3)
所有家长的构造者都被召唤。事实上,内心深处C知道A,因为B扩展了A.例如,如果类A包含方法foo(),那么你可以从C调用foo()。
因此,从您的示例中,C从B调用构造函数,它从A调用构造函数。另外,A也从Object类扩展。所以Object类中的构造函数也被调用!
此外,您不需要添加对super()的调用。如果没有调用父项的构造函数,则super是隐式调用。
答案 3 :(得分:2)
正如你所说,C的构造函数调用B的构造函数来调用A的构造函数。您可以在C对象上调用任何“A”方法,C对象可以在A中看到非私有字段。
即使您在C中覆盖A的方法“foo”,也可以使用“super.foo()”来获取A版本,假设B不会覆盖它。
答案 4 :(得分:1)
就C而言,C中没有覆盖的任何东西都包含在B中,即使在封面下,A类也是实现的地方。
public class A {
public A() {
}
public void aMethod() {
}
}
public class B extends A {
public B() {
super();
}
}
public class C extends B {
public C() {
super();
}
public void doWork() {
super.aMethod();
}
}
所以在这种情况下,A处理aMethod()的实现,即使在C的构造函数中直接调用super()而不是A的构造函数。