抽象類往往用來表征對問題領域進行分析、設計中得出的抽象概念,是對一系列看上去不同,但是本質上相同的具體概念的抽象。
通常在編程語句中用 abstract 修飾的類是抽象類。在C++中,含有純虛擬函式的類稱為抽象類,它不能生成對象;在java中,含有抽象方法的類稱為抽象類,同樣不能生成對象。
抽象類是不完整的,它只能用作基類。在面向對象方法中,抽象類主要用來進行類型隱藏和充當全局變數的角色。
概念理解
c#中的抽象類的特徵
- 抽象類不能實例化。
- 抽象類可以包含抽象方法和抽象訪問器。
- 不能用 sealed 修飾符修飾抽象類,因為這兩個修飾符的含義是相反的。 採用 sealed 修飾符的類無法繼承,而 abstract 修飾符要求對類進行繼承。
- 從抽象類派生的非抽象類必須包括繼承的所有抽象方法和抽象訪問器的實際實現。
比較區別
與具體類比較
- 允許(但不要求)抽象類包含抽象成員。
- 抽象類不能被密封。
與接口比較
- 不能實例化;
- 包含未實現的方法聲明;
- 派生類必須實現未實現的方法,抽象類是抽象方法,接口則是所有成員(不僅是方法包括其他成員)。
- 類可以實現無限個接口,但僅能從一個抽象(或任何其他類型)類繼承,從抽象類派生的類仍可實現接口,從而得出接口是用來解決多重繼承問題的。
- 抽象類當中可以存在非抽象的方法,可接口不能,且它裡面的方法只是一個聲明必須用public來修飾沒有具體實現的方法。
- 抽象類是對象的抽象,然而接口是一種行為規範。
運用要求
C++
C#
- 抽象類應主要用於關係密切的對象,而接口最適合為不相關的類提供通用功能。
- 接口著重於CAN-DO關係類型,而抽象類則偏重於IS-A式的關係。
- 接口多定義對象的行為;抽象類多定義對象的屬性。
- 如果預計會出現版本問題,可以創建“抽象類”。例如,創建了狗(Dog)、雞(Chicken)和鴨(Duck),那么應該考慮抽象出動物(Animal)來應對以後可能出現豬馬牛的事情。而向接口中添加新成員則會強制要求修改所有派生類,並重新編譯,所以版本式的問題最好以抽象類來實現。
- 從抽象類派生的非抽象類必須包括繼承的所有抽象方法和抽象訪問器的實現。
- 對抽象類不能使用new關鍵字,也不能被密封,原因是抽象類不能被實例化。
- 在抽象方法聲明中不能使用 static 或 virtual 修飾符。
Java
- abstract class 在 Java 語言中表示的是一種繼承關係,一個類只能使用一次繼承關係。但是,一個類卻可以實現多個interface。
- 在abstract class 中可以有自己的數據成員,也可以有非abstarct的成員方法,而在interface中,只能夠有靜態的不能被修改的數據成員(也就是必須是static final的,不過在 interface中一般不定義數據成員),所有的成員方法都是abstract的。
- abstract class和interface所反映出的設計理念不同。其實abstract class表示的是"is-a"關係,interface表示的是"like-a"關係。
- 實現抽象類和接口的類必須實現其中的所有方法。抽象類中可以有非抽象方法。接口中則不能有實現方法。
- 接口中定義的變數默認是public static final 型,且必須給其初值,所以實現類中不能重新定義,也不能改變其值。
- 抽象類中的變數默認是 friendly 型,其值可以在子類中重新定義,也可以重新賦值。
- 接口中的方法默認都是 public,abstract 類型的。
運用實例
C++
virtualreturntypefunction()=0;
classA{public:virtualvoidlock(void)=0;virtualvoidunlock(void)=0;virtual~A(void);}
classB:publicA{protected:pthread_mutex_tx;public:B(void);~B(void);virtualvoidlock(void){ead_mutex_lock(x);}virtualvoidunlock(void){ead_mutex_unlock(x);}}
C#
//////定義抽象類///abstractpublicclassAnimal{//定義靜態欄位staticprotectedint_id;//定義屬性publicabstractstaticintId//在抽象方法聲明中不能使用static或virtual修飾符{get;set;}//定義方法publicabstractvoidEat();//定義索引器publicstringthis[inti]{get;//必須聲明主體,因為它未標記為abstract、extern或partialset;}//////實現抽象類///publicclassDog:Animal{publicstaticoverrideintId{get{return_id;}set{_id=value;}}publicoverridevoidEat(){Console.Write("DogEats.")}}
Java
使用abstract class方式定義Door:
abstractclassDoor{abstractvoidopen(); abstractvoidclose();}
interfaceDoor{voidopen(); voidclose();}
abstractclassDoor{ abstractvoidopen(); abstractvoidclose();}interfaceAlarm{ voidalarm();}classAlarmDoorextendsDoorimplementsAlarm{ voidopen(){…} voidclose(){…} voidalarm(){…}}