2010-12-06 161 views
3

嗨,大家好,我在一個問題集中遇到了一個「擴展」問題,我正在處理一個問題集 - 我想我只是有一個塊,因爲它被寫有目的地混淆。這裏是因爲我得到了它的問題:Java - 擴展問題

class A { 
    int x; 
    A(int a) {System.out.println(" class A");} 
} 

class B extends A { 
    int x; 
    B() {System.out.println(" class B");} 
    public static void main (String [] args) { 
    A a = new B(); 
    } 
} 

當我編譯,我得到以下錯誤從控制檯踢出:

cannot find symbol 
symbol : constructor A() 
location: class A 
    B() {System.out.println(" class B");} 
    ^

,我應該能夠解決這個錯誤在B班沒有觸及A班。我明顯錯過了一些顯而易見的東西,但我已經嘗試了一小時所能想到的一切排列,沒有任何工作。

到目前爲止,我已經試過:

  • 在B()的前投擲無效 - 相同的錯誤。
  • 將B()轉換爲A(int a) - 後者返回一個無效的方法聲明錯誤(在它前面添加一個void將我踢回原始的「找不到符號」錯誤)
  • making B ()B(int a) - 同樣的錯誤,加上拋出額外的「無法找到符號」的錯誤,因爲我現在已經拋出了B()聲明。
  • 使B類擴展到B類擴展A(int A) - 拋出9個錯誤。顯然不是答案。
  • 將A的類名更改爲Apple只是爲了查看是否會給我一個答案 - 這要求我在Apple類的A(int a)前添加一個void,這是我無法做到的。

我到底在想什麼?這不完全是一個高級班,所以它不會是非常複雜的任何事情,但這使我完全瘋了。任何幫助將不勝感激。

回答

5

在派生類中,您需要調用基類構造函數。如果你沒有明確地做到這一點,編譯器會嘗試插入對無參數構造函數的調用 - 如果基類中不存在,則會出現該錯誤。

的解決方案是顯式調用基類構造函數的一些值:

B() { 
    super(0); 
    System.out.println(" class B"); 
} 
+0

你打我45秒:) – 2010-12-06 03:23:42

+0

啊 - 我記得我試過這樣做超(a),它扔一個錯誤,可能是因爲我實際上並沒有定義一個。謝謝! – BigE 2010-12-06 03:27:57

+0

@BigE:請點擊左側旁邊的複選框標記爲正確答案。謝謝。 – Asaph 2010-12-06 05:20:23

0

A類沒有默認構造函數,因爲你沒有寫一個(但你沒有寫一個接受一個int參數)。

B類有一個無參數默認構造函數。它需要調用超類的構造函數,但它不能,因爲A類中沒有這樣的東西。

+0

是的,我想到了很多,但我試圖找出如何解決這個問題 - Anon。的文章有解決方案。謝謝! – BigE 2010-12-06 03:30:17

2

你在B的構造函數中的第一次調用需要超級(a); a是無論你想輸入到B的構造函數。

1

1)當擴展一個類時,你的子類隱含地包含一個數據塊,該數據塊包含用於構建超類實例的所有數據。你也必須初始化這些數據。如果您沒有說明它將如何初始化,則假定您需要默認構造函數,即A.A()。但是這個構造函數不存在 - 你只有A.A(int)

爲此初始化,如在B的構造函數的第一行,您對一個構造函數的調用,具有特殊的語法如下:

B() { 
    super(42); 
    // because we are calling the constructor that takes an int, we must supply 
    // one. It's up to you to figure out what values should be supplied. Maybe 
    // you wanted to take an int in the B constructor, and pass it along? 
    System.out.println(" class B"); 
} 

2)你必須在這兩個類中聲明的int x; A和B類。這可能不是你想要的。如上所述,每個B實例已經包含一個int x-它自動獲得的一個,因爲B延伸A.