从你写的情况来看,情况似乎是这样的:
// in a file A.java
public abstract class A {
private int quality;
public A(int quality) {
this.quality = quality;
}
}
// in another file B.java
public abstract class B extends A {
}
编译器将编译这些类,因为当它生成 .class 文件时,它生成的类必须是功能性的。您说“没有任何代码”,但上面是代码。这不是您在任何地方使用的代码。
但是,javac 生成的 .class 文件可以从另一个源链接到。编译器不知道,所以它确保代码编译或生成错误。
在您的情况下,如果您定义了构造函数,则必须显式调用父构造函数或假定默认构造函数。
所以你的 B 类没有定义构造函数。默认构造函数是不可见的。这个默认构造函数只能尝试调用它的超级构造函数。具体来说,它调用父级默认构造函数。除了构造函数不存在。
生成的构造函数不能调用带有 1 个参数的构造函数,因为它不知道为那个参数输入什么。所以基本上如果你有一个构造函数参数,你的子类需要要么提供那个参数,要么你在父级提供一个默认构造函数。
所以这两个都有效:
public abstract class A {
private int quality;
public A(int quality) {
this.quality = quality;
}
}
public abstract class B extends A {
public B() {
super(0);
}
}
或
public abstract class A {
private int quality;
public A() {
this(0);
}
public A(int quality) {
this.quality = quality;
}
}
public abstract class B extends A {
}
在第一种情况下,子类显式调用父构造函数。在第二个中,父母负责知道如何处理该值。
可能在您的情况下(如果您希望另一个类扩展 B 并提供实现)您可能希望这样做:
public abstract class A {
private int quality;
public A(int quality) {
this.quality = quality;
}
}
public abstract class B extends A {
public B(int quality) {
super(quality);
}
}
然后,当您使用非抽象(具体)类扩展此类时,它可以提供价值链。
最后再一次,因为我觉得这是您问题背后的想法:
仅仅因为代码没有在项目的其余部分中使用并不意味着编译器没有尝试创建可用的类。因为您可以从项目中获取任何类文件并将其复制到其他地方并使用它。所以编译器传递的内容必须是正确的,否则会引发错误。