2012-03-09 295 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