原帖地址:http://www.codeproject.com/KB/cs/abstractsvsinterfaces.aspx
原作者:Rahman Mahmoodi
翻譯:54sun
Introduction|介紹
我將通過這篇文章以及所附的demo程序討論一下抽象類(Abstract class)和接口(Interface)。這兩個概念往往會使面嚮對象語言的初學者感到迷惑,因此我嘗試從理論上闡述它們的區別以及在使用的不同。最後我用C#語言來演示如何使用它們。
Background|背景
一個沒有任何實現的抽象類看起來和接口沒有區別!然而,抽象類和接口的區別要遠比它們的共同點來得多。讓我們共同看看它們的相似與區別吧。
What is an Abstract Class?|什麼是抽象類?
抽象類就是一種無法被實例化(instantiated)的特殊的類。那麼,我們需要這麼一個無法生成對象的類呢?很簡單,它的存在就是爲了產生子類。換言之,它只能運行其他的類來繼承它而它不會擁有自己的對象(也叫實例)。它的好處就是可以讓你在實現父類子類這樣的層次結構。簡而言之,抽象類就好比一份合同,使得所有的子類都被強制實行同樣的結構或者標準。
What is an Interface?|什麼是接口?
接口不是類。它一個用關鍵詞interface來定義的實體(譯註,就好比用class來定義類)。一個接口沒有實現,它只定義了函數(或叫方法,下同)聲明而沒有定義函數實現。它和抽象類的一個共同點就是:它也一份規範子類的合同(它聲明的函數名,返回值和參數)。它們的主要不同在於:一個類可以實現多個接口但是隻能繼承一個父類。所以C#不像C++那樣支持多重繼承,而接口可以用來解決這個問題。
Both Together|兩者一起
當我們聲明瞭一個接口,相當於我們聲明瞭一組函數--這些必須由某些類來實現它們。這樣做的好處是它提供一種方式 ,使得一個類可以被分爲兩部分:一部分是通過繼承得來的,另一部分是通過接口得來的。
當我們聲明一個抽象類,相當於我們聲明一個基礎類--它可能已經提供了某些函數具體實現,不過至少必須有一個函數是沒有定義實現的。它的目的就是定義的它的子類可以幹什麼,而至於如何幹就留給了子類去實現。
我通過下面這個表來比較一下接口和抽象類之間的異同:
Feature|特性 |
Interface|接口 |
Abstract class|抽象類 |
Multiple inheritance 多重繼承 |
一個類可以繼承(實現)多個接口。 |
一個類只能繼承一個父類。 |
Default implementation 默認實現 |
接口不能提供函數實現,只能提供函數定義。 |
抽象類可以提供完整的函數實現或者僅僅是在子類應該如何覆蓋父類函數的信息。 |
Access Modfiers 訪問修飾符 |
接口不能用訪問控制符來修飾,函數和屬性都不可以。所有的成員都被認爲是public的。 | 抽象類可以對它的成員(函數、屬性等)使用訪問控制符來修飾。 |
Core VS Peripheral 核心 vs 周邊 |
接口通常用來定義一個類的周邊屬性。換言之,人和車輛這兩個類都可以實現‘可移動’這個接口。 |
抽象類定義一個類的核心屬性也就是這個類的對象們的本質屬性。 |
Homogeneity 同質性 |
如果各種函數實現只不過是有着同樣的函數名,那麼最好通過接口實現。 |
如果各種函數實現很類似,有着同樣的行爲,那麼用抽象類就比較好。 |
Speed 速度 |
需要更多的時間來確定要調用的函數到底在哪個類中。(譯註,應該是指通過接口對象來訪問函數的情形) |
快 |
Adding functionality (Versioning) 擴展性(版本升級) |
如果我們添加一個新函數到接口裏,我們必須檢查所有實現的接口的類以保證每個使用了接口的類都實現了這個新添加的函數。 |
如果我們往抽象類裏面添加一個新函數,並且提供一個默認的實現給此函數,那麼此類的所有子類仍然可以正常工作。. |
Fields and Constants 變量域和常量 |
接口裏面不能定義任何的變量和常量。 |
抽象類可以有變量域和常量這些數據成員存在。 |
Using the Code|代碼
讓我說明一下代碼:我定義了一個抽象類Employee和一個
,在代碼中我也用註釋說明了它們的不同之處。我也通過生成它們的實例來對它們進行測試:我們繼承抽象類Employee得到
Emp_Fulltime;實現
接口
IEmployee得到
Emp_Fulltime2。隨後我們生成了這兩子類的對象(實例)並對它們的屬性進行賦值,再通過調用
calculateWage
來演示如何使用它們。
Abstract Class Employee
Interface Employee
Inherited Objects
Emp_Fulltime
:
Emp_Fulltime2
:
Code for Testing
Conclusion|結論
通過以上的例子,我說明了抽象類和接口之間的區別,並通過一個demo程序演示如何使用抽象類和接口。
License
這篇文章,以及所附的代碼,都遵守:The Code Project Open License (CPOL)
……………………………………………………………………………………………………………………………………………………
爲什麼排版很好,顯示卻不一樣呢。。。