Java 构造函数与继承

Java 构造函数与继承,java,inheritance,constructor,Java,Inheritance,Constructor,我想知道如何在子类中使用超类构造函数,但需要在子类中实例化更少的属性。下面是两门课。我甚至不确定我现在做的事情是否正确。在第二个类中,有一个错误表示“隐式超级构造函数PropertyDB()未定义。必须显式调用另一个构造函数。”请注意,此代码显然不完整,并且有一些代码已注释掉 public abstract class PropertyDB { private int hectares; private String crop; private int lotWidth;

我想知道如何在子类中使用超类构造函数,但需要在子类中实例化更少的属性。下面是两门课。我甚至不确定我现在做的事情是否正确。在第二个类中,有一个错误表示“隐式超级构造函数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;
    }
}

您看到的错误是由于
PropertyDB
类没有默认(无参数)构造函数。在
PropertyDB
中创建它,或者调用现有的超类构造函数
PropertyDB(int-newheams、String-newCrop、int-newLotWidth、int-newLotDepth、int-newBuildingCoverage、int-newLakeFrontage、int-newnumberdrooms、int-newListPrice)
来自
农田
建造商,使用
super
使用
super(新公顷、新玉米、0、0、0、0、新价格)取而代之。0是
int
的默认值。

隐式构造函数
PropertyDB()
仅在未定义任何其他构造函数时才存在,在这种情况下,必须显式定义
PropertyDB()
构造函数

您看到此错误的原因是“隐式超级构造函数PropertyDB()未定义。必须显式调用另一个构造函数”。在
公共农田(int newhemas,int newListPrice,String newCorn)
构造函数中,
super()
自动作为第一条语句调用,它不存在于你的超类中

下面是一个简化的示例:

public class A { }
可以使用
aa=newa()
实例化,因为
public A(){}
是类A的隐式构造函数

public class A {
    public A(int z) { /* do nothing*/ }
}
无法使用
A A=new A()
实例化,因为通过定义显式构造函数
public A(int z)
隐式构造函数不再可用

转到构造函数和继承,从:

如果构造函数体不是以显式构造函数调用开始的,并且所声明的构造函数不是原始类对象的一部分,则编译器会隐式地假定构造函数体以超类构造函数调用“super();”开始,对其直接超类的构造函数的调用,不带任何参数


因此,在您的例子中,
public FarmedLand(int newhemas,int newListPrice,String newCorn)
constructor中执行的第一条语句是对
super()的隐式调用,在您的情况下,它不是隐式定义的(已有一个
公共属性ydb(int,String,…)
构造函数定义)或显式定义的(它不在源代码中)

您的超类只有一个构造函数,因此您的子类构造函数必须调用它。没有办法解决这个问题:超类(例如)有一个
lotWidth
字段,因此子类必须有该字段,而超类在其构造函数中初始化该字段,因此它必须在子类中初始化


因此,除非您以某种方式修改超类,否则您必须在子类构造函数中首先调用
super(…)
,为其所有参数指定值。

当您有一个
扩展
基类的派生类时,基类总是在派生类之前构造。如果没有明确指定基类使用哪个构造函数(如示例中所示),Java会假定您指的是无参数构造函数(在您的示例中是
PropertyDB()
constructor)


但是wait-
PropertyDB
没有无参数构造函数!因此,您唯一的选择是使用
super
,以便Java编译器知道为基类调用哪个构造函数。在您的例子中,只有一个构造函数可供选择,因此您必须将它与所有8个参数一起使用。如果您想使用较少的参数,则必须指定“默认”值(如pass a
0
),或者为采用较少参数的
PropertyDB
定义更多构造函数。

我之前想到过这个解决方案,但如果我不想将任何属性设置为0或null,我该怎么做呢?@ProgrammingKeener类的每个字段都应该有一个值。如果你不显式地设置属性,Java会为你设置它们-对于数值类型,
0
对于布尔值,
false
对于对象类型,
null
我还是个初学者,但这似乎很有帮助。你能详细解释一下吗?