如果我有一个未定义构造函数的子类,但在超类中定义了一个子类,则在实例化该子类对象时,该子类会使用该构造函数吗?
答案 0 :(得分:4)
如果在子类中未定义父类,则该子类是否使用父类构造函数?
这取决于您所说的“使用”。如果您的意思是,子类的默认构造函数会调用父构造函数,那么是的,它会这样做(下文中有更多内容)。如果您的意思是,默认构造函数是与父构造函数自动创建的任何参数匹配的,则不是,通常情况下不会。
当您不为子类声明任何构造函数时,将为您提供default constructor。看起来总是这样
/*same access modifier as the class*/ Child() {
super();
}
基类也有一个默认值,它看起来一样,但是没有super();
。
因此,如果父类具有无参数构造函数(显式或通过默认值),则子类的默认构造函数将成功使用它。但是,如果在父类中定义了一个需要参数的构造函数,则子类将不会编译,因为默认构造函数中的super()
与父类中的构造函数不匹配。
对此进行比较,可以起作用:
public class Parent {
public Parent() { // I could have left this off, since it's the default for a
} // base class; it's here for emphasis
public static void main(String[] args) {
new Child();
}
}
class Child extends Parent {
}
与此一起(向String
构造函数添加了Parent
参数),但失败了:
public class Parent {
public Parent(String s) {
}
public static void main(String[] args) {
new Child();
}
}
class Child extends Parent {
}
第二个失败:
class Child extends Parent { ^ required: String found: no arguments reason: actual and formal argument lists differ in length 1 error
答案 1 :(得分:2)
如果在类中没有编写构造函数,则实际上会添加一个默认构造函数,这可以在字节码中看到:
class A {
}
将为以下代码生成代码:
class A extends Object {
A() {
super();
}
}
每个构造函数都必须调用父类的构造函数作为第一条语句。
同样,这里有一个对super()
的隐式调用。
class B extends A {
B() {
System.out.println();
}
B(int n) {
System.out.println();
}
}
将为
生成代码class B extends A {
B() {
super(); // A()
System.out.println();
}
B(int n) {
super(); // A()
System.out.println();
}
}
这意味着可能会出错,因为给定参数类型没有(重载)构造函数。
另一点是,语句super();
通常没有用。
答案 2 :(得分:1)
假设您有一个扩展父级的空子级:
public class TestChild extends TestParent{
}
父母的样子:
public class TestParent {
private String testStr;
public TestParent() {
this.testStr = "I exist in the child class!";
}
public String getTestStr() {
return testStr;
}
public void setTestStr(String testStr) {
this.testStr = testStr;
}
}
然后在主体中创建子对象,并使用以下命令将其打印出来:
TestChild test = new TestChild();
System.out.println(test.getTestStr());
结果将打印出来:
I exist in the child class!
发生这种情况是因为子类将自动调用super
类的no-arg构造函数。因此,您无需在子类中明确需要构造函数,因为它将自动为您生成默认构造函数。