所有类至少有一个构造函数。如果一个课没有 显式声明任何,Java编译器自动提供 无参构造函数,称为默认构造函数。这个默认值 构造函数调用类父类的无参构造函数,或者 如果类没有其他父对象,则为对象构造函数。 如果父母有 没有构造函数(Object确实有一个),编译器会拒绝 计划。
(source)
但是,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 {
}
答案 0 :(得分:6)
首先是一些术语:
所以所有类都至少有一个构造函数。
子类构造函数可以指定他们在执行子类构造函数中的代码之前,首先在超类中执行哪个构造函数调用。
如果子类构造函数没有指定要调用的超类构造函数,那么编译器将自动调用超类中的可访问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&#39的no-args构造函数是私有的。