2014-01-23 82 views
-1

我是OO設計/編程新手,有一個問題我相信是關於類設計的。我會用我的術語來精確。類設計和繼承

[編輯] 也許歸結爲這樣:我有一個基類類型的對象列表。派生類是作爲實現基類方法的基類的特定類型創建的,而某些派生類具有特定於派生類型的附加參數和/或方法。當我橫過列表時,我正在使用基類參考。什麼是訪問特定變體類的方法和參數的好方法?切換語句並投射?這不是C#中的這種糟糕的形式,並且在類設計中提出缺陷嗎?假設我正在編寫一個使用基類「shape」和類「circle」,「triangle」的圖形程序,和「形狀」派生的「方形」。根據Stroustrup的說法,基類必須包含爲形狀類實現「全套操作」所需的成員函數。在大多數情況下,這些成員函數將是虛擬的,以便派生類可以實現特定於其形狀的功能,例如:加載,保存,繪製,旋轉,更新等。這對我來說都是有意義的。

我陷入困境的地方在於形狀類型之間的細微差別以及這些差異對基類的影響。例如,考慮特定於派生形狀的成員函數。假設「圓」形狀具有描述用多少線段來近似圓的值(例如lineCount)。我如何處理設置和更新這個值的方式,不會以虛擬成員函數從每個派生類的特定需求中「冒泡」開始污染我的基類?

我問這是因爲期望保持一個類型「形狀」的列表來跟蹤我的所有對象。我不希望列出類型爲「circle」,「triangle」和「square」的地方,直接訪問圓圈特定的lineCount值,並且不會讓這些單獨的列表無論如何違反繼承的整個想法隱式或明確地引入switch語句的等價物以及每種形狀類型的案例?

爲了解決這個問題,我在正確的軌道上認爲除了像「draw」這樣明顯的成員函數之外,我還必須深入思考「全套操作」的要求。所以如果我有一個形狀特定的值(例如圓形的lineCount),它必須可以通過形狀的成員函數來獲得/設置該值的一般方式,與其他(可能不同)其他形狀類型。因此,我只能認爲形狀類必須包含一個通用參數設置功能,可以包括要求每個派生類呈現其自己的UI形式,以請求其特定形狀的特定參數。形狀類的要求包括UI成員函數感覺就像形狀類變得太重了。

我在想這個方法嗎?有更好的方法來處理派生類中的細微差異嗎?

+0

解決這個問題的一種方法是爲配置數據配置'std :: map'(或'Dictionary'),並且可以調用一個虛擬'configure'函數來傳遞每種形狀類型所需的數據。 –

+0

所有的子類都應該在基類中實現「全套操作」。但這並不意味着基類應該支持任何子類可能擁有的所有操作。只需將這些函數放入需要它的子類中即可。 – user2079303

+0

Zac,您的評論與解決所有需要lineCount值的特殊問題有關,其中一個lineCount值存儲爲配置參數可應用於所有圈子。如果是這樣,我相信我明白你在說什麼。但是我的問題更一般,每種特定的形狀類型都有其獨特的獨特價值。是否有比「完整的操作」更好的解決方案,或者對列表中存儲的類型對象使用強制轉換/開關語句? – BobC

回答

0

user2079303的觀點是一個很好的觀點,我認爲您可能會對「全套操作」語言感到困惑 - 這意味着Shape類應該知道如何處理您想要做的所有事情這並不是說它應該知道如何去做任何你想要做的事情,以圓形和三角形等等。只有在Circle類中有changeLineCount()方法纔可以,如果可以的話,只能更改Circle對象(您知道的東西絕對是圓圈)而不是Shape對象的行數(可能是也可能不是圓圈)。

我無法想象一種情況,你想改變你不知道的事情的行數是圓圈。如果改變行數對矩形沒有意義(我不知道它會如何),使用switch語句來查明某個事物是否是一個圓是沒有意義的。

+0

同意lineCount對矩形沒有意義。什麼導致我最困惑的是,一旦圓形類對象被放入形狀列表中,我不知道讓它們回到圓形的好方法,以便我可以訪問成員函數。正在鑄造正確的路?從我讀的內容來看,像C#這樣的強類型語言,如果我正在投射,那麼我在我的設計中做錯了什麼。 – BobC

+0

@BobC不把所有這些優秀的風格規則都視爲絕對的,爲什麼你認爲如果使用它是錯誤的呢?按類型切換是「不好的」,因爲當添加新類型時,您必須到處去並修復所有這些切換。現在如果你有限的,很少擴展的類型(如圖形編輯器中的形狀)?另一個問題是爲什麼你的形狀(大概是由用戶通過UI創建的)知道如何渲染自己?這就是您想要在形狀界面中公開渲染算法細節的原因。 –

0

您需要考慮lineCount對矩形的意義。 如果你發現這個概念適用於所有形狀,那麼它是一個很好的候選人,可以放入shape類。 另一方面,如果矩形沒有意義,那麼它可能只屬於圈子類。

現在如果你有一個shape的數組,你應該忽略實際的實現。如果只有圓圈有lineCount那很好,但是當你使用形狀數組時,你將不會使用與lineCount有關的任何東西,因爲它不適用於所有形狀(設置lineCount爲什麼意味着矩形?)

+0

好的,我只把lineCount作爲circle類的成員函數。現在,當我通過形狀列表引用一個圓形對象時,我再也看不到LineCount成員函數。當我想要在圓形上使用此成員函數時,我必須將形狀引用投射到圓類。這是好的形式嗎? – BobC