为什么编译器会抱怨超类没有构造函数,当默认的构造函数被自动赋予一个没有构造函数的类?

问题描述:

所有类都至少有一个构造函数。如果一个类不显式声明任何类,则Java编译器会自动提供一个名为默认构造函数的无参构造函数 。如果该类没有其他父类,则此构造函数的默认构造函数将调用父类的无参数构造函数,或者 对象构造函数。 如果父代有 没有构造函数(Object有一个),编译器会拒绝 程序。为什么编译器会抱怨超类没有构造函数,当默认的构造函数被自动赋予一个没有构造函数的类?

source

不过呢,Object是Java中的每个类的(直接或间接)父。

假设我们有一个类A,它没有明确扩展任何类,所以它隐式扩展了Object。另外假设,A没有明确提供构造函数,因此编译器会自动添加一个默认的构造函数,它将调用其超类(并且Object确实具有构造函数)的构造函数。

现在假设我们有一个扩展类A的类B,它没有提供显式构造函数,所以编译器自动为它提供一个默认的构造函数;这个默认构造函数试图从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 { 
} 
+6

你测试过了吗?我绝对期待这一点。 –

+0

@LouisWasserman不,信任它,因为它在*官方* Java教程。 – Solace

+2

仅仅因为它的官方并不意味着它是有道理的。它只是说所有类在段落的开头至少有一个构造函数!所以没有没有构造函数的东西。 –

首先一些术语:

  • 无参数构造:无参数的构造;
  • 可访问的无参数构造函数:超类中的无参数构造函数对子类可见。这意味着它是公开的或受保护的,或者如果两个类都在同一个包中,则包访问;和
  • 默认构造函数:编译器在类中没有显式构造函数时添加的公共无参数构造函数。

所以所有的类都至少有一个构造函数。

子类构造函数可能指定在执行子类的构造函数中的代码之前调用超类中的哪个构造函数。

如果子类构造函数未指定要调用哪个超类构造函数,则编译器将自动调用超类中的可访问无参数构造函数。

如果超类没有无参数构造函数或者它不可访问,那么未指定要调用的超类构造函数(在子类构造函数中)是编译器错误,因此它必须指定必须

例如:

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的无参数构造函数是私有的。