2012-03-09 250 views
1

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

回答

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

如果构造体不明确的构造函数调用,并正在申报的构造开始不是原始类对象的一部分,那么构造体由编译器隐含地假定以超类构造函数调用“super();”开头,该超类构造函数调用其直接超类的构造函数的调用,其不带任何参数。

所以你的情况在public FarmedLand(int newHectares, int newListPrice, String newCorn)构造函数中执行的第一个语句是​​隐式调用,而你的情况是不是隐含定义(不过已经有了public PropertyDB(int, String, ...)构造函数中定义)或明确(它不是在源代码中)

+0

我仍然是初学者,但这似乎很有帮助。你能详细解释一下吗? – 2012-03-09 03:30:02

0

你看到的错误是由于事实PropertyDB类没有一个默认的(无参数)构造函数。可以在PropertyDB中创建它,或者使用superFarmedLand构造函数中调用现有的超类构造函数PropertyDB(int newHectares, String newCrop, int newLotWidth, int newLotDepth, int newBuildingCoverage, int newLakeFrontage, int newNumBedrooms, int newListPrice)

0

改为使用super(newHectares, newCorn, 0, 0, 0, 0, newListPrice);。无论如何,0是int的默认值。

+0

我早先想到了这个解决方案,但如果我不想将任何属性设置为0或null,我该怎么做呢? – 2012-03-09 03:27:53

+0

@ProgrammingKeener该类的每个字段都应该有一个值。 – 2012-03-09 03:29:02

+0

如果不明确设置属性,Java会为您设置它们 - 数字类型为'0',布尔值为'false',对象类型为'null' – 2012-03-09 03:29:36

0

你的超类只有一个构造函数,所以你的子类构造函数必须调用它。这是没有办法的:超类具有(例如)lotWidth字段,所以子类必须具有该字段,并且超类在其构造函数中初始化该字段,所以它必须在子类中初始化。

因此,除非以某种方式修改超类,否则必须调用super(...)作为子类构造函数中的第一件事,为其所有参数指定值。

1

当你有一个派生类extends的基类,基类始终构造派生类之前。如果你没有明确指定基类使用哪个构造函数(如你的例子),Java假定你的意思是无参数构造函数(在你的情况下是PropertyDB()的构造函数)。

但等 - PropertyDB没有无参数的构造函数!所以你唯一的选择是使用super,以便Java编译器知道哪个构造函数要调用基类。在你的情况下,只有一个构造函数可供选择,所以你必须使用它的所有8个参数。如果您想使用较少的参数,则必须指定“默认”值(例如,通过0),否则定义更多构造函数用于参数较少的PropertyDB