VB.NET之旅(十)—何時用接口。本站提示廣大學習愛好者:(VB.NET之旅(十)—何時用接口)文章只能為提供參考,不一定能成為您想要的結果。以下是VB.NET之旅(十)—何時用接口正文
大李沒通知我接口與籠統類的區別,什麼時分用接口,什麼時分用完成承繼。 弄得我中飯也沒吃好,老在揣摩這事,這不,一吃完飯,我就沖上樓,一個房間 一個房間轉,四處找大李。
過了好一陣,這老哥才和幾個同事說說笑笑地 回到辦公室,我立刻走上前,半請半拉地把他拽到電腦旁。“大李哥,我實 在想得頭暈,既然在VB.NET中接口有了這麼大的開展空間,在方式上與籠統類如 此類似,那麼它們有什麼區別?什麼時分用接口呢?”
聽著我一連 串的問題,大李淺笑著搖搖頭,拍拍我的肩膀說:“小兄弟,不光是你弄不 清,其實就是很有經歷的順序設計師也對什麼時分用接口,什麼時分用籠統類而 頭痛咧。”
此話一出,我更是疑惑重重。不過反而安下心來,老鳥 們都弄不清的問題,我不清楚也不用心中不安了。哈……
大 李看著我忽憂忽喜的表情顯露了一絲驚訝,不過他沒有理睬,持續說:“但 是這個問題我們還是有必要好好剖析一下,讓我們更明白接口與籠統類的詳細含 義。”
“我們早說過,籠統類是一種不能實例化而必需從中繼 承的類。籠統類可以完全完成,但更罕見的是局部完成或許基本不完成,從而封 裝承繼類的通用功用,它可以提供已完成的成員,因而,可以用籠統類確保特定 數量的相反功用,但不能用接口這樣做。”
“接口是完全籠統 的成員集合,它的成員都無法在接口定義時完成,我們可以將它看作是為操作定 義合同,接口的完成完全留給開發者去做。它們之間的區別,假如仔細剖析,還 是有不少的:在VB.NET中,類只能是從一個基類承繼,所以假如要運用籠統類為 一組類提供多態性,這些類必需都是從那個類承繼的;接口就不一樣了,它不但 可以用一個類或構造完成多個接口,一個接口還可以有多個完成。 ”
“也就是說,它們在提供多態性的問題上是有差異的? ”我好象聽懂了點什麼。
“這是一個重要的區別,我們也可以 從多態性的角度來思索是要運用接口還是用籠統類。”大李贊同了我的觀念 ,“假如估計要創立組件的多個版本,我們應該創立籠統類。這是由於,抽 象類提供復雜易行的辦法來控制組件版本。經過更新基類,一切承繼類都隨更改 自動更新。這是益處,當然也是問題,對吧?(詳見前文《軟弱的基類》)另一 方面,接口一旦創立就不能更改。假如需求接口的新版本,必需創立一個全新的 接口。所以,假如創立的功用將在大范圍的全異對象間運用,則運用接口。 ”
我想了一下,接著大李的話說:“能不能這樣說,籠統類主 要用於關系親密的對象,而接口最合適為不相關的類提供通用功用。 ”
大李對我伸出了大拇指:“不錯,小伙子悟性很好呀!你想 ,我上午跟你說,要創立控件,首先就是要對一些接口停止完成以讓零碎可以識 別(詳見前文《接口》)。而各個控件之間的聯絡其實關聯性並不大。所以,它 們的根底大都是接口。但是,我們要留意一點,在組件設計時,假如要在組件的 一切完成間提供通用的已完成功用,則運用籠統類。這是由於我們方才說過的原 因,籠統類允許局部完成類,而接口不包括任何成員的完成。 ”
“唔,明白了,它們之間的區別有點明白了。”我默 默地點了搖頭。
“另外,有個通用的設計思想,假如要設計小而簡 練的功用塊,則運用接口。假如要設計大的功用單元,則運用籠統類。”大 李又補充了一條建議。
“看來設計的問題還是蠻大的,普通來說, 怎樣設計接口呢?”我接著問。
“為什麼你所看到的編程書籍 也好,順序例程也好,極少有對接口的描繪,而對類完成承繼的例子屈指可數? 這就從一個正面給我們提了一個醒,假如運用適當,接口可以成為很有用的工具 。但假如運用不當,它們會變得十分順手,甚至阻礙無效的編程。接口的設計與 運用其實是一項拙劣的藝術。”大李鄭重其事的說。
“藝術? ”我驚叫了一聲。
“沒錯,藝術!”大李又減輕了一下 語氣,“經過接口與完成的方式,我們可以將同一類型的順序運用在不同的 對象下面,而且不用修正原有類,絕對子順序必需經過修正源順序代碼才干夠達 到重用的目的,接口與完成不只是偉大的提高,也是境界極高的順序設計藝術。 ”
“哦,這倒是真的。”我回想起明天看到的接口的例 程。
“但是,最大的問題還是集中在接口設計上。”大李接著 說,“接口一旦被定義和承受,就必需堅持不變,以維護為運用該接口而編 寫的使用順序。接口發布後,就不能對其停止更改。這是我們停止組件設計的一 個重要准繩,叫做‘接口不變性’。”
我點了搖頭: “接口不變性,這個我可以了解了。”
“我曾經反重復 復強調過,創立一個接口就是在創立一個定義,接口定義發布後則永遠不能更改 。接口不變性,就是為了維護為運用接口而編寫的現有零碎。當接口設計與需求 有所出入,確認需求大幅度變卦時,我們應該創立新的接口。普通命名方式是, 新接口可以經過在原來的接口稱號後追加一個數字‘2’來命名,以顯 示出它與現有接口的關系。然後經過接口承繼來創立新接口。 ”
“可是,假如需求剖析得不好,豈不是會呈現一大堆的派生 接口了?”我難免有點顧忌。
“這是一定的,而且過於頻繁地 生成新接口,會因未運用的接口完成而使組件變得很龐大。有經歷的設計師,在 充沛剖析需求後,設計出的接口往往很小且互相獨立,增加了功能問題發作的可 能。”
“這種分解才能倒真的是藝術呀!”我不由為之 歎服。
“當然,普通來說,我們會把確定哪些屬性和辦法屬於接口 的設計進程稱為‘接口分解’。根本原則是,應在一個接口中將嚴密 相關的幾個功用聚合為一組。功用太多會使接口方便於運轉,而過於細分功用將 招致額定的零碎開支並降低運用的簡易性。掌握分解的這個度的才能是需求不時 的在技術上停止磨煉,以及在對每個項目深化剖析與了解的根底上才干失掉的。 ”
“明白了。”我大聲地答復著,真希望自己能早一天 成為接口設計巨匠。
大李笑著拍了拍我:“明白了就好。其實,與 設計接口相比,創立大的完成承繼樹更容易出錯。”
“當然, ”我腦海裡顯現起完成承繼的各個環節,“這是不是說,在某些時分 適當運用接口還是很無益的。”
“看來你真的明白了,那你再 來說一下,接口與類完成承繼相比,益處有什麼?”大李回過身開端找茶杯 。
我低下頭,努力地轉動了一下腦子:“我試著說一下吧,總體而 言,接口是一種十分無效的編程辦法,它讓對象的定義與完成別離,從而可以在 不毀壞現有使用順序的狀況下使對象得以完善與退化。接口消弭了完成承繼的一 個大問題,就是在對設計施行後再對其停止更改時很能夠對代碼發生毀壞。即便 完成承繼允許類從基類承繼完成,在類初次發布時依然會使我們不得不為設計做 很多的選擇。假如原有的想象不正確,並非總可以在當前的版本中對代碼停止安 全的更改。比方,我們定義了一個基類的辦法,它需求一個 Integer 參數,然後 來又確定該參數應該為 Long 數據類型。我們無法平安更改原始類,由於為從原 始類派生的類所設計的使用順序能夠無法停止正確編譯。這一問題會擴展化,因 為單個基類會影響幾百個子類。”
“那用重載原始類並采用一 個Long類型的參數,不就能處理這個問題了嗎?”大李提了個問題。
“這個麼?”我想了一下,“可是,這樣不一定能到達 稱心的效果,由於一個派生類能夠需求對采用整數的辦法停止重寫,假如取 Long 數據類型的辦法不能被重寫,該派生類能夠無法正常運轉。 ”
“那用接口怎樣做?”大李不依不撓地持續問。
“方法就是發布承受新數據類型的更新接口。”我一下子就回 答出來了。
“看來你曾經掌握了接口操作的根本環節了。”大 李的評語真讓我快樂。“我再幫你總結一下,運用接口承繼而不必類承繼的 次要緣由有:在使用順序要求很多能夠不相關的對象類型以提供某種功用的狀況 下,用接口適用性會更強;接口比基類更靈敏,由於可以定義單個完成來完成多 個接口;在無需從基類承繼完成的狀況下,接口更好;在無法運用類承繼的狀況 下接口是很有用的。例如,構造無法從類承繼,但它們可以完成接口。 ”
我抿著嘴用力點了搖頭,同時在心裡默默地記憶著大李所說的每 一條原則。
“回去好好想想,多寫幾個小順序來練習一下,今天我 們還要欣賞VB.NET提供的弱小的可視承繼的表現呢。”