"构造函数调用必须是构造函数中的第一个语句"在Java代码中获得错误?

时间:2014-05-20 12:58:09

标签: java inheritance constructor

我在此代码中遇到两个错误

  1. 构造函数调用必须是构造函数中的第一个语句。

  2. 隐式超级构造函数Parent()未定义。必须显式调用另一个构造函数。

  3. 所以请帮我解决这些问题。

    class Parent
    {
      public Parent(int x, int y,int z)
      {
        System.out.println("Created Parent");
      }
    }
    public class Child extends Parent
    {
      Child(int x)// error 2   
      {
    
      }
      Child(int x, int y)// error 2
      {
      }
      Child(int x, int y, int z)
      {
        this(x);
        super(x,y,z);// error 2
        System.out.println("Creating child");
        this(x,y);// error 1
      }
      public static void main(String [] args)
      {
        Child c=new Child(1,2,3);
      }
    }
    

5 个答案:

答案 0 :(得分:2)

答案就在问题中。您必须在子类构造函数中的任何其他语句之前调用父类构造函数。

public class Child extends Parent
{
Child(int x)// error 2   
{
   super(0,0,0);
}
Child(int x, int y)// error 2
{
   super(x,y,0);
}
Child(int x, int y, int z)
{
 super(x,y,z);

 System.out.println("Creating child");

}
如果base具有默认构造函数,那么

对基础构造函数的调用不是必需的,在代码中不是这种情况。

这背后的理论是,在任何继承层次结构中,当你实例化任何派生对象时,首先要初始化最顶层的基础,然后是下一个,依此类推,直到实际的派生点。

答案 1 :(得分:2)

构造函数必须做的第一件事就是调用父类构造函数。

隐式默认值为super()(没有任何参数),但这在您的情况下不起作用,因为父类Parent没有无参数构造函数,它只有一个三个int参数,所以你需要调用那个。

你需要在构造函数的第一行中这样做。

您也可以在同一个类上调用另一个构造函数(另一个this()),而不是调用超级构造函数。假定超级构造函数被其他构造函数调用(否则它将无法编译)。

但是你必须在构造函数的第一行调用this()

在您拨打this()super()后,您无法再次拨打电话。


 Child(int x)// error 2   
 {

 }

不编译,因为没有super()来匹配隐式调用。

Child(int x, int y)// error 2
{
}

同样的问题。

Child(int x, int y, int z)
{
  this(x);
  super(x,y,z);// error 2
  System.out.println("Creating child");
  this(x,y);// error 1
}

除第一行外,您无法拨打super()this()

答案 2 :(得分:2)

您需要了解四件事:

  • 如果您未指定任何显式构造函数调用,编译器会为您插入对super()的调用。

  • 对于任何构造函数(显式或隐式super()调用,必须有一个构造函数调用。 (你的Child(int, int, int)构造函数中有三个。

  • 显式构造函数调用必须是构造函数体中的第一个语句。

  • 您只能调用实际存在的构造函数 - 因此从super()调用Child正在Parent中查找不存在的无参数构造函数。

一个常见的模式是拥有一个“主”构造函数,其他构造函数位于同一个类链中,然后将其链接到超类。例如:

Child(int x)
{
    this(x, 0); // Chains to the Child(int, int) constructor, defaulting y to 0
}

Child(int x, int y)
{
    // Chains to the Child(int, int, int) constructor, defaulting z to 0
    this(x, y, 0);
}

Child(int x, int y, int z)
{
    super(x, y, z);
    System.out.println("Creating child");
}

答案 3 :(得分:1)

当你创建一个新的Child类实例时,首先要做的是调用super(x,y,z),否则它无法工作。实际上Child是一个“Parent”,因此要拥有Child的实例,您必须能够实例化超类。所以Child(int x){super(x,0,0);}是Child类的可能构造函数,但Child(int x){}不是因为Parent类没有默认构造函数。请记住,当您向类中明确添加构造函数时,默认的构造函数不再可用。最后,你写的构造函数:Child(int x,int y,int z){this(x);超级(X,Y,Z); this(x,y);}无法工作,因为在构造函数中,您调用了三个不同的构造函数,但是您希望拥有多少个实例?每个构造函数只能创建一个实例。

答案 4 :(得分:1)

实例化子对象时,调用构造函数的顺序是 家长--->其次是儿童。 所以构造函数中的第一行必须是对父构造函数的调用。 (如果你没有自己提供,编译器会为你插入一个。)或者调用自己重载的构造函数(如上所述将调用super)。

导致错误1的原因是您在执行某些可执行语句后才调用了构造函数。

错误2 ... 你必须知道的第一件事是,如果你不提供任何类型的构造函数,编译器将为每个类提供一个默认的无参数构造函数。

但是那一刻,你提供了一个构造函数,编译器不再给你一个默认的构造函数。你需要自己写一个。

第二件事,默认情况下,如果你的子类中没有super(),编译器默认会对super()进行无参数调用。

这就是你的问题所在。

您已为父级提供了参数化构造函数,因此编译器未提供no-arg默认构造函数。而现在,当你的孩子班级你没有自己的超级(xy,z)调用时,它将调用默认的无法arg()。但是父母没有AGR构造者......因此错误。

你可以做两件事来解决这个问题,要么写一个     父(){}

构造

或明确调用super - > 超级(0,0,0) 在每个子构造函数中