Java调用超级构造函数混淆

时间:2015-09-25 04:36:22

标签: java

class Yfk {
public static void main(String[] args) {
     System.out.println(new YfkC().x);
  }
}
abstract class YfkA {
int x = 3;
  YfkA() { x++; }
}
class YfkB extends YfkA {}
class YfkC extends YfkB {}

最终结果是4.我不清楚扩展过程。在main函数中,我们创建一个对象YfkC并调用Yfkc.x.我的理解是因为没有方法并且在类yfkc中存档,所以我们在yfkb中找到,然后在yfkc中找到。在这个时候,YfkC会自动升级到YfkA吗?等于System.out.println(new YfkA().x);因此我们会得到x = 4;我对从YfkCYfkA的过程感到困惑。

3 个答案:

答案 0 :(得分:2)

new YfkC().x

这内部调用子类的构造函数。所以x的值递增并打印为4。

YfkC() -> YfkB() -> YfkA() { x++;};

每个类的默认构造函数都在调用super();。这会在执行它之前调用超类的默认构造函数。

如果你想了解构造函数链接,那么将系统排除并查看调用链。

public  class Yfk {
  public static void main(String[] args) {
    System.out.println(new YfkC().x);
  }
}
abstract class YfkA {
  int x = 3;
  YfkA() {
    System.out.println("YfkA");
    x++; }
}
class YfkB extends YfkA {
  public YfkB() {
    System.out.println("YfkB");
  }
}
class YfkC extends YfkB {
  public YfkC() {
    System.out.println("YfkC");
  }
}

输出:
YfkA
YfkB
YfkC
4

答案 1 :(得分:1)

调用任何子构造函数时。从当前类中对直接父类构造函数进行链调用。并且调用将继续,直到Object类构造函数调用,因为可能的大多数父类是超类。

以下是构造函数在继承中的行为的示例

 public class ParentClass {  
      public ParentClass() {  
           System.out.println("Parent default constructor invoked");  
      }  
      public ParentClass(int a) {  
           System.out.println("Parent argumented constructor invoked");  
      }  
      public static void main(String[] args) {  
           SubSubClass sub = new SubSubClass();  
      }  
 }  
 class SubClass extends ParentClass {  
      public SubClass() {// not calling any super  
           System.out.println("Child default constructor invoked");  
      }  
      public SubClass(int b) {  
           super(b);  
           System.out.println("Child default constructor invoked");  
      }  
 }  
 class SubSubClass extends SubClass {  
      public SubSubClass() {// not calling any super  
           System.out.println("Sub Child default constructor invoked");  
      }  
      public SubSubClass(int b) {  
           super(b);  
           System.out.println("Sub Child default constructor invoked");  
      }  
 }  
 OUTPUT:  
 Parent default constructor invoked  
 Child default constructor invoked  
 Sub Child default constructor invoked

我写了一篇涉及这个主题的文章,希望能够清除你的怀疑。

Constructor inheritance(ovveriding) and reasons behind restricting constructor inheritance in Java

答案 2 :(得分:0)

每当子类被实例化时,它的父构造函数将按顺序在链中向上调用。

在您的层次结构中,您有:

  • YfkC
  • YfkB
  • abstract YfkA
  • Object

...并且在每个构造函数中都有一个对super()的隐式调用。

因此,new YfkC调用YfkB的构造函数,该构造函数调用抽象类的YfkA构造函数,从而导致x的增量。

如果你再次执行new YfkC().x,那么你得到5,因为每次你新建YfkA个孩子时,你都会调用那个构造函数。