[英]Alternatives to using overridden methods in constructors, Java
在我編寫的Java項目中,我最終使用了在構造函數中重寫的方法。 就像是:
class SuperClass {
SuperClass() {
intialise();
}
protected void initialise() {
//Do some stuff common to all subclasses
methodA();
methodB();
}
protected abstract void methodA();
protected abstract void methodB();
}
class SubClass1() {
SubClass() {
super();
}
protected void methodA() { //Do something }
protected void methodB() { //Do something }
}
class SubClass2() {
SubClass() {
super();
}
protected void methodA() { //Do something else }
protected void methodB() { //Do something else}
}
我現在意識到,雖然在我的情況下它工作正常,但是有點危險,因為SubClass方法在一個目前只被構造為SuperClass對象的對象上調用(當擴展SuperClass的新類被添加時,可能會忽略這一點)未來)。 由於對象的創建方式不同,它在c ++中也不起作用。
我能想到的唯一方法就是將initialise方法調用向下移動到具體的類構造函數:
class SuperClass {
SuperClass() {
}
protected void initialise() {
methodA();
methodB();
}
protected abstract void methodA();
protected abstract void methodB();
}
class SubClass1() {
SubClass() {
super();
initialise();
}
protected void methodA() { //Do something }
protected void methodB() { //Do something }
}...
這是解決這個問題的常用方法嗎? 擴展SuperClass的所有其他類需要記住調用initialise()似乎是一種恥辱(並且容易忘記)。
我還發現自己在更復雜的情境中做了類似的事情,它在構造函數中使用了Factory方法,在子類中重寫它以決定實現哪個具體類。 我能想到的唯一另一種方法是將這種設計模式保持原樣,或許可以構建一個兩階段的過程; 即用最小的構造,然后調用第二種方法來完成工作。
需要初始化的對象實際上需要通過工廠方法創建。 你確實提到了一個工廠,但是從構造函數中調用,所以這聽起來也不像是簡單的方法。 如果你只是在基類中有一個工廠,公共不可見的構造函數,以及一個決定返回哪個具體類的機制,那么工廠將很容易地執行初始化策略。
這實際上不是一個好主意,因為當調用其methodA()和methodB()時,您的子類將無法正確構造。 對於擴展課程的人來說,這將是非常混亂的。 建議您使用抽象的init()
,如dlev在他/她的評論中所建議的那樣。
我想知道你是否讓事情變得比他們需要的更復雜。
在您的示例中,methodA的每個實現所完成的工作可以移動到執行該實現的類的構造函數中。 因此,不要使用SubClass :: methodA,只需將邏輯移動到SubClass構造函數中。
如果你這樣做,你可以獲得清晰,代價是可能難以理解對各種初始化位執行順序的控制。
Bruce Eckel在他的“Thinking in Java”中提出的建議是使你的methodA()和類SuperClass的方法B()最終或私有(隱式最終),因此它們可以從超類構造函數訪問,盡管沒有派生類會有訪問這些方法,因此,不會有任何危險的覆蓋 - 任何派生類中聲明的類似簽名的任何方法都只是新方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.