CLR via C 設計時 用基類還是介面

2021-10-02 04:19:19 字數 1432 閱讀 3899

應該設計基類還是介面不能一概而論。

1.is-a(「屬於」)對比can-do(「能做某事」)關係

型別只能繼承乙個實現。如果派生型別和基型別建立不起is-a關係,就不用基類而用介面。介面意味著can-do關係。如果多種物件型別都「能」做某事,就為它們建立介面。例如,乙個型別能將自己的例項轉換為另乙個型別(iconcertible),乙個型別能序列化自己的例項(iserializable)。注意,值型別必須從system.valuetype派生,所以不能從乙個任意的基類派生。這是必須使用can-do關係並定義介面。

2.易用性

對於開發人員,定義從基類派生的新型別通常比實現介面的所有方法容易得多。基型別可提供大量功能,所以派生型別可能只需稍作改動。而提供介面的話,新型別必須實現所有成員。

3.一致性實現

無論介面協定(contract)訂立得有多好,都無法保證所有人百分百正確使用它。而如果為基類提供良好的預設實現,那麼一開始得到的就是能正常工作並經過良好測試的型別。以後根據需要修改就可以了。

4.版本問題

向基類新增乙個方法,派生型別將繼承新方法。一開始使用的就是乙個能正常工作的型別,使用者的源**甚至不需要重新編譯。而向介面新增新成員,會強迫介面的繼承者更改其源**並重新編譯。

fcl中涉及資料流處理(streaming data)的類採用的是實現繼承方案(即繼承基類的實現)。system.io.stream是抽象基類,提供了包括read和write在內的一組方法。其他類(system.io.filestream,system.io.memorystream和system.net.sockets.networkstream)都從stream派生。在這三個類中,每乙個和stream都是is-a關係,這使具體類的實現變得更容易。例如,派生類只需實現同步i/o操作,非同步i/o操作已經從stream基類繼承了。

必須承認,為流類(***stream)選擇繼承的理由不是特別充分,因為stream基類實際只提供了很少的實現。

相反,microsoft採用基於介面的方式來設計fcl中的集合。system.collection.gemeric命名空間定義了幾個與集合有關的介面:ienumerable,icollection,ilist和idictionary。然後,microsoft提供了大量類來實現這些介面組合,包括list,dictionary,queue和stact等等。設計者在類和介面之間選擇了can-do關係,因為不同集合類的實現迥然有異。換句話說,集合類之間沒有多少能共享的**。

不過,這些集合類提供的操作相當一致。例如,都維護了一組可列舉的元素,而且都允許新增和刪除元素。

最後要說的是,兩件事情實際能同時做:定義介面,同時提供實現該介面的基類。

例如,fcl定義了icomparer介面,任何型別都可選擇實現該介面。此外,fcl提供了抽象基類comparer,它實現了該介面,同時為非泛型icomparer的compare方法提供了預設實現。介面定義和基類同時存在帶來了很大的靈活性,開發人員可根據需要選擇其中乙個。

android 新建專案基類設計

轉 看到這個圖感覺熟悉的兄弟姐妹們就可以直接略過本篇啦.因為我要將要把它們乙個個地拿出來長篇大論咯。1 2 應用程式實體3 author change4 5 6public 7private activitymanager activitymanager null activity管理類 8priv...

C 設計抽象基類的策略

1 分析相關物件的需求,設計出一組實現公共功能的函式。2 將這些函式作為基類的虛函式 或純虛函式 它們定義了乙個 統一的公共介面。3 由該類基類派生出若干子類,在各子類中實現這些虛函式。includeusing namespace std class container 抽象類 virtual do...

類層次設計時的靈活處理

多型設計時候的一些小技巧,通過加入一層抽象類,減少後續的改動,如在抽象基類或者介面中加入新的method,此時並不需要在所有的實現類中去實現,只需要在需要實現的類中去實現處理,在抽象類中提供預設的實現,當然出現此種情況介面可能設計的時候存在一定的不合理,但是在實際的情況確實會出現不合理。public...