2009-06-09 26 views
5

如果我有一個抽象類以及該類的派生類,那麼根據良好和實踐的設計慣例,我是否正確地認爲派生類不應提供額外的公共方法(它們只應實現抽象類並可以選擇重寫父類方法)?派生類中的額外公共方法?

此外,爲每個派生類使用不同的構造方法簽名是否可接受?

+0

*編輯*僅供參考,您正在從工廠構建一個對象的情況。我爭辯說,在工廠的情況下,調用代碼應該知道派生類有哪些方法。 – 2009-06-09 17:36:27

回答

5

就我個人而言,我看不出有任何問題。

至於在派生類額外的公共方法:

有用處有限,在此,在許多情況下。當類被轉換或設置爲對基類的引用時,額外的方法將不可用,這嚴重限制了這種做法的實用性。這就是說,這種方法沒有什麼特別的錯誤。子類是爲了添加特定的行爲 - 有時候,在類層次結構中,子類中的新行爲不適用於基類。如果子類將自己頻繁使用,那麼在方法中對額外行爲進行建模似乎是完全合理的。

至於構造函數簽名 -

我也沒有看到這個問題。子類通常需要比抽象類更多的信息才能進入可用狀態。這就是說,我通常確保在基類中實現每個構造函數,並添加子類所需的新參數。

話雖這麼說:

除非有充分的理由,我會避免與比基類...參數少一個子類的構造函數,爲什麼我能夠在更一般的情況下,指定的東西,不是具體情況?我發現當子類與基類有完全不同的構造選項時,通常會引起混淆。

+0

如果你是從一個工廠構建一個對象,那麼我說得對,應該沒有額外的公共方法?在工廠的情況下,調用代碼是否應該知道預期會有什麼方法? – 2009-06-09 17:31:02

+0

這取決於 - 即使從工廠構建,工廠也需要知道對象的編譯時類型(以便調用相應的構造函數)。它可以「瞭解」額外的參數。在這種情況下,它只是取決於場景,將如何使用,等等。 – 2009-06-09 17:43:53

1

將額外的公共方法添加到派生類是完全可以接受的。給他們不同的構造者也是完全可以接受的。 (其實,這是很常見的。)

0

派生類不應該提供額外的公共方法

狗可以做的事情,一個動物不能?

此外,每個派生類有不同的構造方法簽名是可以接受的嗎?

這裏沒有問題。派生類型不需要匹配其兄弟姐妹或父母的構造函數簽名。

+0

回答年齡問題,是一隻狗可以做一些動物不能做的事......比如樹皮,咬,跑,棚,跳等......蠕蟲是動物,(它們不是植物) - 和一個蠕蟲不能做任何這些事情...... – 2009-06-09 19:11:33

2

這是派生類的美。

雖然Pen類可能具有write()函數,但延伸Pen的RetractablePen類也可能具有retractPoint()函數。

當你擴展一個類時,它意味着 - 從字面上 - 擴展它的功能。

+0

如果你是從一個工廠構建一個對象,那麼我說對了,我不應該有額外的公共方法?在工廠的情況下,調用代碼是否應該知道預期會有什麼方法? – 2009-06-09 17:37:31

1

不,這是完全合理的(有時是非常必要的設計)添加額外的公共方法。考慮具有Location成員和Size方法的Shape抽象基類的(完全設計的)情況。例如,當您從Shape派生Polygon時,例如,您可能想要添加一個名爲GetNumberOfSides()的公共方法;例如,但是當你從Shape派生Circle時,你不想擁有這個。

以同樣的方式,派生類型可能會有非常不同的構造要求;在定義抽象基類時,不可能知道所有需求可能是什麼,所以請隨意選擇不同的簽名。僅僅因爲你的被激怒的類型對於抽象基類是多態的,並不意味着那個基類對你如何實現在該基類中定義的抽象強加了嚴格的限制;無論你想要什麼,你都可以自由地做到這一點。

2

一般來說很好。

你想避免的是使用通用中的特定。即

foreach(Animal a in myFarm.Animals) 
{ 
    a.Feed(); 
    // this is a bit grim 
    if(a is Horse) 
    { 
     ((Horse)a).CleanStable(); 
    } 
} 

因此,這不是增加公共法的行爲,而是你來自哪裏,打電話給他們。

0

這不僅是可以接受的,對於構造函數來說通常是不同的。例如,如果我們有一個(不變)Rectangle類,並擴展它的(不變)Square,廣場的構造應該是(使用Java的時刻)

public Square(double size) 

Rectangle構造將是

public Rectangle(double width, double height) 

需要做的事情是子類構造函數應該調用一些適當的超類構造函數。

至於額外的公共方法,它可能取決於使用。對於Square案例,我不會添加任何額外的方法。然而,在Java中,存在Writer 的子類PrintWriter,其目的是添加一些便利方法。在這種情況下,我認爲它可以(Java肯定有一些不好的例子,但我不認爲這是其中之一)。我也希望有一些額外的方法容器/子類型的可能性。

你不應該做的是改變超類方法的方式,違反了超類的期望。

相關問題