All classes have at least one constructor. If a class does not explicitly declare any, the Java compiler automatically provides a no-argument constructor, called the default constructor. This default constructor calls the class parent's no-argument constructor, or the Object constructor if the class has no other parent. If the parent has no constructor (Object does have one), the compiler will reject the program.
( source )
但是,Object
是 Java 中每个类的(直接或间接)父类(super class)。
假设,我们有一个类 A
,它没有显式扩展任何类,因此它隐式扩展 Object
。还假设,A
没有显式提供构造函数,因此编译器会自动为其添加一个默认构造函数,该构造函数将调用其父类(super class) Object
的构造函数。 (并且 Object
确实有一个构造函数)。
现在假设我们有一个类 B
扩展类 A
,并且它不提供显式构造函数,因此编译器会自动为其提供默认构造函数;此默认构造函数尝试调用 A
中的构造函数.
现在为什么 B
中出现编译器错误,当编译器为 A
提供了一个(默认)构造函数时(它正在调用 Object
的构造函数,而 Object
有一个)?
编辑:
测试:编译成功! 这是否意味着教程中的最后一句话不正确?
class A extends B {
public static void main(String [] args) {
//A a = new A();
System.out.println("Yayyy");
}
}
class B {
}
最佳答案
首先是一些术语:
- 无参数构造函数:没有参数的构造函数;
- 可访问的无参数构造函数:父类(super class)中的无参数构造函数对子类可见。这意味着它要么是公共(public)的,要么是 protected ,或者,如果两个类位于同一个包中,则为包访问;和
- 默认构造函数:当类中没有显式构造函数时,编译器添加的公共(public)无参数构造函数。
因此所有类都至少有一个构造函数。
子类构造函数可能首先指定在执行子类构造函数中的代码之前调用父类(super class)中的哪个构造函数。
如果子类构造函数没有指定调用哪个父类(super class)构造函数,则编译器将自动调用父类(super class)中可访问的无参数构造函数。
如果父类(super class)没有无参数构造函数或者不可访问,则不指定要调用的父类(super class)构造函数(在子类构造函数中)会出现编译器错误,因此必须指定它。
例如:
public class Base { }
public class Derived extends Base { }
这很好,因为如果您没有显式添加构造函数,Java 会为您添加一个公共(public)默认构造函数。
public class Base { }
public class Derived extends Base { public Derived(int i) { } }
也可以。
public class Base { public Base(String s) { } }
public class Derived extends Base { }
上面是一个编译错误,因为 Base 没有默认构造函数。
public class Base { private Base() { } }
public class Derived extends Base { }
这也是一个错误,因为 Base 的无参数构造函数是私有(private)的。
关于java - 当没有构造函数的类的默认构造函数是 'automatically' 时,为什么编译器会提示父类(super class)没有构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35589454/