|
抽象類和接口是對于面向?qū)ο笾袑τ诔橄箢惗x進(jìn)行支持的兩種機(jī)制,正是由于這兩種機(jī)制的存在,才具有了強(qiáng)大的面向?qū)ο竽芰Αbstract class和interface之間在對于抽象類定義的支持方面具有很大的相似性,甚至可以相互替換,因此很多開發(fā)者在進(jìn)行抽象類定義時對于abstract class和interface的選擇顯得比較隨意。其實(shí),兩者之間還是有很大的區(qū)別的,對于它們的選擇甚至反映出對于問題領(lǐng)域本質(zhì)的理解、對于設(shè)計意圖的理解是否正確、合理。本文將對它們之間的區(qū)別進(jìn)行一番剖析,試圖給開發(fā)者提供一個在二者之間進(jìn)行選擇的依據(jù)。
理解抽象類
抽象類和接口在.NET中都是用來進(jìn)行抽象類(本文中的抽象類并非從abstract class翻譯而來,它表示的是一個抽象體,而abstract class為.NET語言中用于定義抽象類的一種方法,請讀者注意區(qū)分)定義的,那么什么是抽象類,使用抽象類能為我們帶來什么好處呢?
在面向?qū)ο蟮母拍钪校覀冎浪械膶ο蠖际峭ㄟ^類來描繪的,但是反過來卻不是這樣。并不是所有的類都是用來描繪對象的,如果一個類中沒有包含足夠的信息來描繪一個具體的對象,這樣的類就是抽象類。抽象類往往用來表征我們在對問題領(lǐng)域進(jìn)行分析、設(shè)計中得出的抽象概念,是對一系列看上去不同,但是本質(zhì)上相同的具體概念的抽象。比如:如果我們進(jìn)行一個圖形編輯軟件的開發(fā),就會發(fā)現(xiàn)問題領(lǐng)域存在著圓、三角形這樣一些具體概念,它們是不同的,但是它們又都屬于形狀這樣一個概念,形狀這個概念在問題領(lǐng)域是不存在的,它就是一個抽象概念。正是因為抽象的概念在問題領(lǐng)域沒有對應(yīng)的具體概念,所以用以表征抽象概念的抽象類是不能夠?qū)嵗摹?/p>
在面向?qū)ο箢I(lǐng)域,抽象類主要用來進(jìn)行類型隱藏。我們可以構(gòu)造出一個固定的一組行為的抽象描述,但是這組行為卻能夠有任意個可能的具體實(shí)現(xiàn)方式。這個抽象描述就是抽象類,而這一組任意個可能的具體實(shí)現(xiàn)則表現(xiàn)為所有可能的派生類。模塊可以操作一個抽象體。由于模塊依賴于一個固定的抽象體,因此它可以是不允許修改的;同時,通過從這個抽象體派生,也可擴(kuò)展此模塊的行為功能。熟悉OCP的讀者一定知道,為了能夠?qū)崿F(xiàn)面向?qū)ο笤O(shè)計的一個最核心的原則OCP( Open-Closed Principle),抽象類是其中的關(guān)鍵所在。
從語法定義層面看abstract class和interface
在語法層面,對于abstract class和interface給出了不同的定義方式,下面以定義一個名為Demo的抽象類為例來說明這種不同。
使用abstract class的方式定義Demo抽象類的方式如下:
abstract class Demo {
abstract void method1();
abstract void method2();
…
}
從設(shè)計理念層面看abstract class和interface
上面主要從語法定義和編程的角度論述了abstract class和interface的區(qū)別,這些層面的區(qū)別是比較低層次的、非本質(zhì)的。本小節(jié)將從另一個層面:abstract class和interface所反映出的設(shè)計理念,來分析一下二者的區(qū)別。作者認(rèn)為,從這個層面進(jìn)行分析才能理解二者概念的本質(zhì)所在。
前面已經(jīng)提到過,abstarct class在.NET語言中體現(xiàn)了一種繼承關(guān)系,要想使得繼承關(guān)系合理,父類和派生類之間必須存在"is a"關(guān)系,即父類和派生類在概念本質(zhì)上應(yīng)該是相同的(參考文獻(xiàn)〔3〕中有關(guān)于"is a"關(guān)系的大篇幅深入的論述,有興趣的讀者可以參考)。對于interface 來說則不然,并不要求interface的實(shí)現(xiàn)者和interface定義在概念本質(zhì)上是一致的,僅僅是實(shí)現(xiàn)了interface定義的契約而已。為了使論述便于理解,下面將通過一個簡單的實(shí)例進(jìn)行說明。
考慮這樣一個例子,假設(shè)在我們的問題領(lǐng)域中有一個關(guān)于Door的抽象概念,該Door具有執(zhí)行兩個動作open和close,此時我們可以通過abstract class或者interface來定義一個表示該抽象概念的類型,定義方式分別如下所示:
使用abstract class方式定義Door:
abstract class Door {
abstract void open();
abstract void close();
}
NET技術(shù):深入理解抽象類和接口,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。