Re: [問題] 一個設計上的問題(virtual function)

看板C_and_CPP作者 (高髮箍)時間11年前 (2012/12/16 06:30), 編輯推噓1(100)
留言1則, 1人參與, 最新討論串3/3 (看更多)
如果類別間的關係能用 composition 建立, 而且作得簡潔漂亮, 就別 用 inheritance. 至少有兩個該用 has-a 關係的理由 1. Attributes 型態全為 builtin types 一般書上常舉的例子: Employee,其實應為 EmployeeData,內含身 為一個雇員應有的資料(名字、地址、薪水等),功能上和C語言的   結構相去不了多少。如果你的 Employee 長得就像這樣,那就是該用 has-a建立關係的理由,例如:program manager has employee data2. 除了 setter/getter 以外, 沒有其他名稱中有 "動詞" 的 methods 物件依行為模式, 大抵上可分為 (a) 生物 (b) 無生物兩種. 生物通 常為了服務別人、或者被服務而被創造出來, 像是 提供/取用系統資 源,或者運算資源等;無生物則是無具備前述條件,用來搭建服務的 基本元件。 舉例來說如果你的 Employee 不像 Animal 一樣會有 walk()、run() 等 methods, 那麼Employee 應改稱為 EmployeeData, 如此一來也不 會進而考慮到該不該繼承的問題。 不要為了方便使用而繼承 是責任不是福利 類別可以分為兩個部分:(a) 介面 (b) 屬性。 介面是提供服務的媒介。所以一旦介面和父類別的相同,甚至直接由父類 別繼承而來,可以料想到的是:「使用者會把子類認為是和父類一樣的服 務提供者」。提供與父類別異質的服務,程式碼將會變得怪異無比,使用 者如果為此而增加程式碼來切換使用服務(就如同你的程式碼),父類別的 介面就形同虛設。 雖然可以透過語法直接存取繼承下來的屬性,但是如果你未曾想過去擴充 父類別的服務,使用繼承反而讓兩個類別關係緊密到就像一個,使用者最 後會偏向於 "只" 使用其中一種。 ───────────── 我是分隔線 ───────────── 如果想做到 ProgramManager has EmployeeData 而且又透過 method 來 取用這些資料,可以導入一個中間層: class HasEmployeeData { EmployeeData data; public: string getName() const { return data.getName(); } }; class ProgramManager : public HasEmployeeData { }; 如果看到這裡還是覺得繼承才是較佳的解法,仍有下面問題需再考慮: 1. 這裡是否有必要先用父類別指標指向該物件,卻要在使用的時候    頻繁轉型?    如果是,那麼 (1) 轉型以及 (2) 對特定子類別物件作存取的程 式碼應該分別抽取出來成為新的函式,去除這部分對子類別的相 依性。 另外對於你所提出來 pure virtual function 的方案,我倒不認為那可 以成為解決方案。 1. 如果為了部分子類別而設立介面(非全體),那麼你就應該是那些 子類別。意思是,這個父類別沒有存在的必要。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.121.197.115

12/16 11:40, , 1F
推薦這篇文章
12/16 11:40, 1F
文章代碼(AID): #1GpFdnTK (C_and_CPP)
文章代碼(AID): #1GpFdnTK (C_and_CPP)