抽象類和接口有不少相相似的用法,甚至在某些時候能夠相互替換使用,很容易搞混淆,因此在進行抽象類定義時對於abstract class和interface的選擇時就比較隨意。其實不管是從使用方法仍是在設計思想方案來看,兩者的區別仍是很大的。
先來看看什麼是abstract class,C#容許把類和方法聲明爲abstract,即抽象類和抽象方法。
abstract class一般表明一個抽象概念,提供一個繼承的出發點。
在面向對象的概念中,咱們知道全部對象都是經過類來描繪的,可是反過來卻不必定是這樣,並非全部的類都是用來描繪對象的,若是一個類中沒有包含了足夠的信息來描繪一個具體的對象,這樣的類就是abstract class。abstract class每每用來表達一個咱們在對問題領域進行分析、設計中得出的一個抽象概念,是對一些看上去不一樣可是本質上相同的具體概念的抽象。
好比咱們在開一個動物園管理系統時,動物園裏動物有猴子、老虎、大象等這樣一些具體的對象,猴子、老虎、大象均可以統稱爲動物,動物就是這樣的一個抽象的概念,若是描述一個老虎長什麼樣子咱們都是能夠作的到的,若是描述一個動物長什麼樣子呢,相信誰都作不到,由於現實中不存在這樣一個對象。
再看interface,interface是把隱式公共方法和屬性組合起來,以封裝特定功能的一個集合,一旦實現了interface,類就能夠支持interface所指定的全部屬性和成員。上面咱們先從概念上理解了abstract class和interface,下面咱們用一個demo來講明abstract class和interface在使用上的一些特色,在c#中定義抽象類以下:
public abstract class Animal
{
public abstract String GetSountSound();
}
定義接口以下:
public interface IAnimal
{
String GetSountSound();
}
在abstract class的方式中,Animal能夠有本身的數據成員,也能夠有非抽象的成員方法,而在interface的實現方式中,IAnimal中只能有靜態的不能被修改的數據成員,不過在interface中通常不定義數據成員,全部的成員方法都是不包含方法體的。雖然從編程的角度來看,abstract class和interface均可以用來實現面向抽象編程的思想,可是在具體使用上仍是有一些區別的。
abstract class在C#中是一個類,是用來被繼承的,一個類只能使用一次幾成關係;可是一個類能夠實現多個interface。其次在abstract class在中是能夠有非抽象方法的,而在interface的定義中,全部方法都必須是抽象的,也就是沒有方法體的。上面從語法定義和編程的角度咱們論述了abstract class在和interface的區別,下面咱們從設計理念的層面上分析一下兩者的本質區別。前面提到過,abstract class在是被用來繼承的,要想使集成關係合理,父類和子類之間必須存在「is a」的關係,即父類和派生類在概念本質上是相同的,對於interface來講則否則,並不要求interface的實現者和interface定義上在概念本質上是一致的,僅僅是實現了interface定義的契約而已。
也就是說:類是對對象的抽象,abstract class在是對類的抽象,interface是對行爲的抽象;若是行爲跨越了不一樣類的對象,可以使用interface,對於一些類似的類對象,用繼承abstract class在;從設計角度講,abstract class在是從子類中發現了公共的東西,泛化出父類,而後子類繼承父類,而interface是根本不知道子類的存在,方法如何實現還不肯定,預先定義。
總結幾句話來講:
一、abstract class在和interface都不能直接實例化,若是要實例化,abstract class在變量必須指向實現全部抽象方法的子類對象,interface變量必須指向實現全部interfacing方法的類對象。
二、abstract class在要被子類繼承,interface要被類實現。
三、interface只能作方法聲明,abstract class在中能夠作方法聲明,也能夠作方法實現
四、interface裏定義的變量只能是公共的靜態的常量,abstract class在中的變量是普通變量。
五、abstract class在裏的抽象方法必須所有被子類所實現,若是子類不能所有實現父類抽象方法,那麼該子類只能是abstract class在。一樣,一個實現interface的時候,如不能所有實現接口方法,那麼該類也只能爲abstract class在。
六、抽象方法只能申明,不能實現。abstract void abc();不能寫成abstract void abc(){}。
七、abstract class在裏能夠沒有抽象方法
八、若是一個類裏有抽象方法,那麼這個類只能是abstract class在
九、抽象方法要被實現,因此不能是靜態的,也不能是私有的。
十、interface可繼承interface,並可多繼承interface,但類只能單根繼承。
抽象方法與虛方法
抽象方法是隻有定義、沒有實際方法體的函數,它只能在抽象函數中出現,而且在子類中必須重寫;虛方法則有本身的函數體,已經提供了函數實現,可是容許在子類中重寫或覆蓋。重寫的子類虛函數就是被覆蓋了。
抽象方法
使用abstract關鍵字 public abstract bool Withdraw(…);
抽象方法是必須被派生類覆寫的方法。
抽象方法是能夠當作是沒有實現體的虛方法
若是類中包含抽象方法,那麼類就必須定義爲抽象類,不管是否還包含其它通常方法。
虛方法
使用virtual關鍵字 public virtual bool Withdraw(…);
調用虛方法,運行時將肯定調用對象是什麼類的實例,並調用適當的覆寫的方法。
虛方法能夠有實現體 若一個實例方法的聲明中含有 virtual 修飾符,則稱該方法爲虛擬方法;
一個虛擬方法的實現能夠由派生類取代。取代所繼承的虛擬方法的實現的過程稱爲重寫該方法;在一個虛擬方法調用中,該調用所涉及的那個實例的運行時類型肯定了要被調用的到底是該方法的哪個實現。