2012-05-20 23 views
2

當我延長一些類,例如:Java的構造延長

public class First { 
    int id; 
    public First(int _id) { 
     id = _id; 
    } 
} 

public class Second extends First { 

} 

我要重新聲明構造函數二等功,當我需要做的僅僅是相同的。 我:

public Second(int _id) { 
    super(_id); 
} 

但每次我改變父類的構造所有的擴展類的構造時需要進行編輯。

如何完全擴展構造函數?

該死的,不要告訴我電話和天線,我已經多次使用OOP。

現在我只問 - 我不能在擴展類上寫公共Class(){},並使用父構造函數嗎?

看來我不行。好的。

+9

你不能?這是它的工作原理。你改變了超級構造函數中的某些東西,你必須改變所有繼承它的子元素。 – OmniOwl

+0

它對我來說很尷尬,我不敢相信java不能。 – ShadowPrince

+3

假設您的父級是電話,並且電話需要屏幕和天線才能構建。如果子類實例被允許在沒有天線的情況下構建,它們就不再是電話了。但是,您可能會在父類中提供一個構造函數,它只將屏幕作爲參數,並使用默認天線。 –

回答

1

此限制是爲什麼我比繼承更喜歡構圖的原因之一。考慮使用像這樣的,而不是代碼:

public class Second { 
    private final First first; 

    public Second(final First first) { 
     this.first=first; 
    } 

    public int getId() { 
     return first.getId(); 
    } 
} 

這種結構也使您的兩個班少耦合並使得類在我看來更清晰的關係。有關繼承的組合更詳盡的討論,請參閱此問題:Prefer composition over inheritance?

7

定義子類時,它不會從超類繼承構造函數。對於默認超類構造函數以外的任何其他內容,都需要在每個子類構造函數中顯式調用超類構造函數。 (這意味着,除其他外,如果基類沒有默認構造函數, 每個子類構造函數都不能有任何子類 顯式調用超類構造函數—並且沒有子類可以只有編譯器生成的默認值構造函數)

繼承構造函數可能會導致各種問題。試想一下,這樣的事情:

class Base { 
    private int mId; 
    public Base(int id) { 
     mId = id; 
    } 
    . . . 
} 

現在,我們希望獲得具有第二屬性—,我們要確保是從來沒有null標籤—類。因此,我們寫:

class Derived extends Base { 
    private Object mTag; 
    public Derived(Object tag, int id) { 
     super(id); 
     if (tag == null) { 
      throw new IllegalArgumentException("tag cannot be null"); 
     } 
     mTag = tag; 
    } 
    . . . 
} 

現在想象構建的Derived一個實例是這樣的:

Derived derived = new Derived(3); 

如果構造函數被繼承,這大概也是合法的。這意味着什麼?首先,mTag將被設置爲其默認值nullDerived將無法​​執行所有Derived實例必須具有非空標記的規則。在需要更多打字的代價下,Java排除了繼承構造函數的精確性,允許每個類完全控制其實例的創建方式。

+0

我只想不爲每個類輸入構造函數,並使用父類的構造函數。不好,但不可能,我明白了。 – ShadowPrince

+0

@ShadowPrince IDE的eclipse可以從超類生成構造函數,也許這實際上是你在尋找什麼? –