Sol*_*ace 0 java inheritance constructor object default-constructor
所有类至少有一个构造函数.如果类没有显式声明任何类,那么Java编译器会自动提供一个无参构造函数,称为默认构造函数.此默认构造函数调用类parent的无参数构造函数,如果类没有其他父级,则调用Object构造函数.如果父级没有构造函数(Object确实有构造函数),编译器将拒绝该程序.
(来源)
但是,它Object是Java中每个类的(直接或间接)超类.
假设,我们有一个类A,它不会显式扩展任何类,因此它会隐式扩展Object.另外假设,A没有明确地提供构造函数,因此编译器会自动添加一个默认构造函数,它将调用其超类的构造函数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 {
}
首先是一些术语:
所以所有类都至少有一个构造函数.
子类构造函数可以指定他们在执行子类构造函数中的代码之前,首先在超类中执行哪些构造函数调用.
如果子类构造函数未指定要调用的超类构造函数,则编译器将自动调用超类中的可访问no-args构造函数.
如果超类没有no-arg构造函数或者它不可访问,那么不指定要调用的超类构造函数(在子类构造函数中)是编译器错误,因此必须指定它.
例如:
public class Base { }
public class Derived extends Base { }
这很好,因为如果你没有显式地添加构造函数,那么Java就会为你提供公共默认构造函数.
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的no-args构造函数是私有的.