我在此代码中遇到两个错误
构造函数调用必须是构造函数中的第一个语句。
隐式超级构造函数Parent()未定义。必须显式调用另一个构造函数。
所以请帮我解决这些问题。
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);
}
}
答案 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) 在每个子构造函数中