2011-04-24 55 views
5

我正在考慮使用抽象類與所有抽象成員,而不是一個接口,以避免顯式接口實現鍋爐代碼。因此,而不是不使用抽象類而不使用接口的原因?

type IMyInterface = 
    abstract Name : string 
    abstract Text : string 

type MyClass() = 
    member __.Name = "name" 
    member __.Text = "text" 
    interface IMyInterface with 
     member this.Name = this.Name 
     member this.Text = this.Text 

我不得不

[<AbstractClass>] 
type MyAbstractClass() = 
    abstract Name : string 
    abstract Text : string 

type MyClass() = 
    inherit MyAbstractClass() 
    override __.Name = "name" 
    override __.Text = "text" 

慎用或影響的任何話,我應該知道的嗎?

+4

如果你在一個接口和一個抽象基類之間作出決定,你也可以考慮使用兩者。提供一個抽象基類型,實現者可以*選擇*繼承,並讓它實現一個接口。然後,接受對接口的引用,而不是ABC。這在每種情況下都不起作用(例如,您的代碼實際上需要ABC中的代碼存在於每個具體實現中,並且不能接受備用實現),但通常可能是一個好主意。 – 2011-04-24 05:04:41

+1

@Merlyn Morgan-Graham - 絕佳的建議!我正在嘗試這種方法,迄今爲止它工作得很好,給了兩全其美。 – 2011-04-24 15:54:47

回答

8

只有你應該意識到並做出有意識的決定的是一個類只能從一個類繼承,但實現了很多接口。


除此之外,使用抽象類和接口的一些建議:

  • 如果預計創建組件的多個版本,創建一個 抽象類。抽象類 爲您的組件提供了一個簡單易用的 版本。通過更新 基類,所有繼承類 自動更新爲 更改。另一方面,接口 一旦創建就無法更改。如果 接口的新版本是 必需的,則必須創建一個全新的 接口。
  • 如果您正在創建的功能在整個不同對象的範圍內有用,請使用 界面。抽象類應該是 主要用於與 密切相關的對象,而接口 最適合爲不相關的類提供常見的 功能。
  • 如果您正在設計小巧簡潔的功能位,請使用 接口。如果您正在設計大型 功能單元,請使用摘要 類。
  • 如果要在組件的所有實現中提供通用實現的功能,請使用抽象類 。抽象類 允許您部分實現您的 類,而接口不包含任何成員的 實現。

http://msdn.microsoft.com/en-us/library/scsyfw1d%28vs.71%29.aspx

就個人而言,我覺得這些建議是當場上。尤其是另一方面,接口一旦創建就無法更改。如果需要新版本的界面,則必須創建一個全新的界面。是非常重要的一點。

+0

對,謝謝 - 那個人也在我的腦海裏浮現出來。肯定是一個biggy。 – 2011-04-24 04:09:57

+1

沒有技術原因的接口不能改變,除非它通過COM暴露。 .Net框架/語言讓你。至於版本控制,除非有很好的理由,否則在公共庫接口上進行重大更改被認爲是不好的做法,但同樣的建議適用於抽象基本類型,即添加額外的抽象成員。 – 2011-04-24 05:00:23

+0

你能解釋一下你的意思嗎?「.Net框架/語言讓你」 – manojlds 2011-04-24 05:09:56

4

斯蒂芬

只有一個,最基本的,並且明顯...一個接口允許替代實施方式;如果「發佈的知名類型」是一個抽象類,那麼您不能在以後提供任何替代方案...所以缺點是你限制你未來的選擇;好處是(取決於有多少繼承者),你可以節省大量的鍋爐代碼。

如果你真的確定沒有其他有效的實現,那麼去抽象類。如果沒有,那麼堅持接口。

我想你可以同時做這兩件事......我想這會給你兩個世界上最好的。

乾杯。基思。

PS:manojlds是正確的,當然...和SOOOO更sucinct ;-)

+0

我認爲使用接口比抽象類限制未來選項更多。如果您發佈界面,如果您的需求發生變化,您將無法在以後更改該界面,因爲任何更改都是重大更改。抽象類更加靈活,因爲您可以添加虛擬成員,並調整內部實現,只要公共抽象方法不會更改其簽名。 – 2011-04-24 04:20:16

+0

馬克,你有一個「有效」的觀點,它不是,恕我直言,這是一個非常「重要」的觀點。根據我的經驗,需要「現有班級的變體」更爲常見;經文「需要添加一個方法到現有的PUBLISHED界面」。很簡單;一旦一個界面到達出版階段,它就會陷入困境;否則你不會發布它,現在你會嗎? – corlettk 2011-04-24 04:40:37

+0

要求可以在發佈後更改,比任何人都想要的更多。考慮一下如果你公開一個插件接口,並且後來發現你需要它比做的更多。使用接口的解決方案是你需要創建一個新的接口,然後你堅持主持多個插件體系結構,其中抽象類,這個問題不存在,因爲新功能可以添加爲虛擬方法。我多次遇到這個問題。我也在不同的開源項目中看到過這幾次。想不到我的頭頂上有什麼。 – 2011-04-24 05:15:56

2

在抽象類,可以實現所有的子類的一些共同的行爲。

在你的界面設計中,你可能想要一個方法調用其他方法來完成一些複合任務。例如,predictAll(Instance array)可能會使用predictSingle(Instance)併爲所有子類提供默認實現。如果使用接口,則需要在所有子類中實現predictAll

但是,這一點作爲多重繼承之一併不重要。我比接口類更喜歡接口。

接口還可以保持您的設計蠟黃。

還有一點: 接口鼓勵更多功能代碼比抽象類。 Haskell中的Typeclass是一個更強大的接口。