使用超类中的构造函数

时间:2009-01-06 20:29:07

标签: java inheritance constructor super

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()我们只是指直接超类的构造函数,无论我们在继承层次结构中有多少其他类。 这不仅适用于构造函数,也适用于任何方法和实例变量。

此致

5 个答案:

答案 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去做多重继承。这是一件坏事。相反,您可以通过使用接口

来实现Java
class 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的构造函数。