我想知道如何在子类中使用超类构造函数,但需要在子类中实例化更少的属性。以下是两个班级。我甚至不确定我目前是否做得对。在第二个类中,有一个错误,表示“隐式超级构造函数PropertyDB()未定义。必须显式调用另一个构造函数。”请注意,此代码显然不完整,并且存在已注释掉的代码。
public abstract class PropertyDB {
private int hectares;
private String crop;
private int lotWidth;
private int lotDepth;
private int buildingCoverage;
private int lakeFrontage;
private int numBedrooms;
private int listPrice;
//public abstract int getPricePerArea();
//public abstract int getPricePerBuildingArea();
public PropertyDB(int newHectares, String newCrop, int newLotWidth, int newLotDepth,
int newBuildingCoverage, int newLakeFrontage, int newNumBedrooms, int newListPrice){
hectares = newHectares;
crop = newCrop;
lotWidth = newLotWidth;
lotDepth = newLotDepth;
buildingCoverage = newBuildingCoverage;
lakeFrontage = newLakeFrontage;
numBedrooms = newNumBedrooms;
listPrice = newListPrice;
}
}
public class FarmedLand extends PropertyDB{
public FarmedLand(int newHectares, int newListPrice, String newCorn){
//super(270, 100, "corn");
hectares = newHectares;
listPrice = newListPrice;
corn = newCorn;
}
}
答案 0 :(得分:2)
隐式构造函数PropertyDB()
仅在您未定义任何其他构造函数时才存在,在这种情况下,您必须显式定义PropertyDB()
构造函数。
您看到此错误的原因“隐式超级构造函数PropertyDB()未定义。必须显式调用另一个构造函数。”在public FarmedLand(int newHectares, int newListPrice, String newCorn)
构造函数中,super()
被自动调用为第一个语句,在您的超类中不存在。
这是一个简化的例子:
public class A { }
可以使用A a = new A()
进行实例化,因为public A() { }
是A类的隐式构造函数。
public class A {
public A(int z) { /* do nothing*/ }
}
不能使用A a = new A()
进行实例化,因为通过定义显式构造函数public A(int z)
,隐式构造函数不再可用。
转到构造函数和继承,来自Java Language Specification section 8.8.7:
如果构造函数体不是以显式构造函数调用开始并且声明的构造函数不是原始类Object的一部分,那么编译器会隐式假设构造函数体以超类构造函数调用“super()开头;“,调用其直接超类的构造函数,不带参数。
所以在你的情况下,public FarmedLand(int newHectares, int newListPrice, String newCorn)
构造函数中执行的第一个语句是对super();
的隐式调用,在你的情况下没有隐式定义(已经定义了public PropertyDB(int, String, ...)
构造函数)或者显式(它不在源代码中)
答案 1 :(得分:1)
当你有一个extends
基类的派生类时,基类总是在派生类之前构造。如果没有明确指定要用于基类的构造函数(如示例所示),那么Java假定您指的是无参数构造函数(在您的情况下是PropertyDB()
构造函数)。
但等等 - PropertyDB
没有无参数构造函数!因此,您唯一的选择是使用super
,以便Java编译器知道要为基类调用哪个构造函数。在您的情况下,只有一个构造函数可供选择,因此您必须将它与所有8个参数一起使用。如果要使用较少的参数,则必须指定“default”值(如传递0
),或者为PropertyDB
定义更多参数的构造函数。
答案 2 :(得分:0)
您目击的错误是由于PropertyDB
类没有默认(无参数)构造函数。在PropertyDB
中创建它,或使用PropertyDB(int newHectares, String newCrop, int newLotWidth, int newLotDepth, int newBuildingCoverage, int newLakeFrontage, int newNumBedrooms, int newListPrice)
从FarmedLand
构造函数调用现有的超类构造函数super
。
答案 3 :(得分:0)
请改用super(newHectares, newCorn, 0, 0, 0, 0, newListPrice);
。无论如何,0是int
的默认值。
答案 4 :(得分:0)
您的超类只有一个构造函数,因此您的子类构造函数必须调用它。没有办法解决这个问题:超类有(例如)一个lotWidth
字段,因此子类必须具有该字段,并且超类在其构造函数中初始化该字段,因此它必须在子类中初始化。 / p>
因此,除非您以某种方式修改超类,否则您将不得不在子类构造函数中调用super(...)
,为其所有参数指定值。