宿遷經(jīng)貿(mào)高等職業(yè)技術(shù)學(xué)校 毛廣敏
C#中抽象類(lèi)與接口的分析與比較
宿遷經(jīng)貿(mào)高等職業(yè)技術(shù)學(xué)校 毛廣敏
抽象類(lèi)和接口是C#語(yǔ)言中兩個(gè)重要的對(duì)象引用類(lèi)型,是C#程序設(shè)計(jì)使用多態(tài)性的基礎(chǔ),但也是初學(xué)者容易搞混淆的兩種類(lèi)型,本文主要介紹了兩者的概念、特點(diǎn)和典型應(yīng)用實(shí)例,并對(duì)兩者進(jìn)行比較。
抽象類(lèi);接口;分析;區(qū)別
抽象類(lèi)和接口是C#語(yǔ)言中兩個(gè)重要的對(duì)象引用類(lèi)型,是C#程序設(shè)計(jì)使用多態(tài)性的基礎(chǔ),但也是初學(xué)者容易搞混淆的兩種類(lèi)型,本文主要介紹了兩者的概念、特點(diǎn)和典型應(yīng)用實(shí)例,并對(duì)兩者進(jìn)行比較。通過(guò)本文的介紹能使得初學(xué)者掌握抽象類(lèi)和接口概念、特點(diǎn)和使用場(chǎng)合。
在類(lèi)聲明中使用abstract修飾符的類(lèi)稱(chēng)為抽象類(lèi)。含有一個(gè)或一個(gè)以上的抽象成員的類(lèi),必須定義為抽象類(lèi)。當(dāng)方法聲明包含abstract修飾符時(shí),稱(chēng)該方法為抽象方法,雖然抽象方法同時(shí)隱含為虛擬方法,但是它不能有virtual修飾符。聲明中包含abstract修飾的屬性稱(chēng)為抽象屬性。抽象方法或?qū)傩詻](méi)有方法體或?qū)傩栽L問(wèn)器。抽象類(lèi)只能是其他類(lèi)的基類(lèi),抽象類(lèi)不能實(shí)例化,必須在繼承中實(shí)現(xiàn)。抽象類(lèi)中可以包含非抽象成員。抽象類(lèi)的目的是提供一個(gè)合適的基類(lèi),以派生其他的類(lèi)。使用抽象類(lèi)的好處之一是,當(dāng)要求組建新版本時(shí),可根據(jù)需要將附加方法添加到基類(lèi)。如下例:
抽象類(lèi)應(yīng)用實(shí)例:
從上面的例子可以看出在程序中聲明了一個(gè)抽象類(lèi)animal,在該類(lèi)中聲明了一個(gè)抽象方法FoodHabits(),該方法沒(méi)有形參,無(wú)返回值。Carnivorous和Herbivorous是animal的派生類(lèi),在這兩個(gè)派生類(lèi)中必須重寫(xiě)FoodHabits()方法,否則會(huì)發(fā)生編譯錯(cuò)誤,重寫(xiě)方法的關(guān)鍵字是override。在主函數(shù)中不可以創(chuàng)建基類(lèi)animal的實(shí)例,但可以將實(shí)現(xiàn)抽象類(lèi)的對(duì)象賦給抽象類(lèi)的對(duì)象。
在C#中類(lèi)只能實(shí)現(xiàn)“單一繼承”,要實(shí)現(xiàn)多重繼承,必須使用接口。一個(gè)接口定義一個(gè)協(xié)定,實(shí)現(xiàn)接口的類(lèi)或結(jié)構(gòu)必須遵守其協(xié)定。接口可以從多個(gè)基接口繼承,而類(lèi)或結(jié)構(gòu)可以實(shí)現(xiàn)多個(gè)接口中。接口聲明可以聲明零個(gè)或多個(gè)成員,接口的成員必須是方法、屬性、事件或索引器。接口不以包含常數(shù)、字段、運(yùn)算符、實(shí)例構(gòu)造函數(shù)、析構(gòu)函數(shù)或類(lèi)型,也不能包含任何種類(lèi)的靜態(tài)成員。接口本身不提供它所定義的成員的實(shí)現(xiàn),接口只指定實(shí)現(xiàn)該接口的類(lèi)或接口必須提供的成員。所有接口成員都隱式地具有public訪問(wèn)權(quán)限。類(lèi)可以從單個(gè)類(lèi)繼承但可以實(shí)現(xiàn)多個(gè)接口,實(shí)現(xiàn)接口的類(lèi)需要實(shí)現(xiàn)接口的所有成員。接口可以從現(xiàn)有接口中繼承,一個(gè)實(shí)現(xiàn)接口的類(lèi)也實(shí)現(xiàn)它的繼承接口的基類(lèi)接口。
雖然不能創(chuàng)建接口對(duì)象,但可以聲明接口變量,接口變量必須指向一個(gè)實(shí)現(xiàn)了接口的類(lèi)的對(duì)象。如下例中的TypeUse[]t=new TypeUse[4];聲明了一個(gè)接口類(lèi)型的數(shù)組,它包含4個(gè)接口類(lèi)型的變量。以下語(yǔ)句聲明了類(lèi)的對(duì)象,并實(shí)例化,接口變量(接口數(shù)組元素)指向類(lèi)的對(duì)象。
以上語(yǔ)句說(shuō)明不同類(lèi)型的對(duì)象被分配給一個(gè)接口引用。以下程序中應(yīng)用程序通過(guò)接口引用數(shù)組調(diào)用Showinfo方法,并返回結(jié)果,在Showinfo方法中引用Type屬性和調(diào)用TellAboutSelf方法,不同對(duì)象及其屬性、方法關(guān)聯(lián)在一起,因此,在引用Type屬性和調(diào)用TellAboutSelf方法時(shí),不必考慮是哪一個(gè)對(duì)象,這也是多態(tài)行為的典型示例。
從上面兩個(gè)關(guān)于抽象類(lèi)和接口的例子中可以看出抽象類(lèi)和接口相似的地方和區(qū)別。
1.抽象類(lèi)和接口都包含可以由派生類(lèi)繼承的成員,兩者都不能直接實(shí)例化。
2.兩者都可以被繼承。3.兩者都不能被實(shí)例化。4.都可以包含方法聲明。
5.派生類(lèi)必須實(shí)現(xiàn)未實(shí)現(xiàn)的方法。
1.類(lèi)是對(duì)對(duì)象的抽象,可以把抽象類(lèi)理解為把類(lèi)當(dāng)作對(duì)象,抽象成的類(lèi)叫做抽象類(lèi)。而接口只是一個(gè)行為的規(guī)范或規(guī)定。
2.抽象類(lèi)是一種不能實(shí)例化而必須從中繼承的類(lèi)。抽象類(lèi)可封裝繼承類(lèi)的通用不變的功能,但也可通過(guò)實(shí)現(xiàn)抽象類(lèi)的抽象方法和屬性為繼承類(lèi)提供其不同的功能。在抽象類(lèi)中可以包含非抽象成員。接口是完全抽象成員集合,可以被看作是為操作定合同。如果類(lèi)實(shí)現(xiàn)了一個(gè)接口,必須實(shí)現(xiàn)接口把定義的所有成員。
3.抽象類(lèi)的派生類(lèi)也必須重寫(xiě)抽象類(lèi)中的抽象方法或?qū)傩?。抽象?lèi)中的成員沒(méi)有限制,但接口中的成員必須是方法、屬性、事件或索引器。所有接口的成員都是隱式具有public訪問(wèn)權(quán)限,并且不能顯式的聲明接口成員的訪問(wèn)權(quán)限,而抽象的成員的訪問(wèn)權(quán)限需指定。
1.如果預(yù)計(jì)要?jiǎng)?chuàng)建組件的多個(gè)版本,則創(chuàng)建抽象類(lèi)。抽象類(lèi)提供簡(jiǎn)單的方法來(lái)控制組件版本。
2.如果創(chuàng)建的功能將在大范圍的全異對(duì)象間使用,則使用接口。如果要設(shè)計(jì)小而簡(jiǎn)練的功能塊,則使用接口。
3.如果要設(shè)計(jì)大的功能單元,則使用抽象類(lèi),如果要在組件的所有實(shí)現(xiàn)間提供通用的已實(shí)現(xiàn)功能,則使用抽象類(lèi)。
4.抽象類(lèi)主要用于關(guān)系密切的對(duì)象,而接口適合為不相關(guān)的類(lèi)提供通用功能。
本文通過(guò)對(duì)抽象類(lèi)和接口概念、特點(diǎn)、典型應(yīng)用實(shí)例、比較分析及使用場(chǎng)合的介紹,相信能對(duì)初學(xué)者有所幫助。
[1]陳銳.C#程序設(shè)計(jì)(高等學(xué)校計(jì)算機(jī)科學(xué)與技術(shù)教材)[M].2012.
[2]杜少杰,王文紅.C#程序設(shè)計(jì)案例教材[M].2010.
[3]胡湘萍.C#中接口與抽象類(lèi)的應(yīng)用辨析[J].2010.
毛廣敏(1978—),女,江蘇沭陽(yáng)人,宿遷經(jīng)貿(mào)高等職業(yè)技術(shù)學(xué)校講師。