版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
.NET面向?qū)ο蟪绦蛟O(shè)計第13章創(chuàng)建接口和定義抽象類本章簡介定義接口在結(jié)構(gòu)或類中實現(xiàn)接口通過接口引用一個類在抽象類中捕獲通用的實現(xiàn)細(xì)節(jié)使用sealed關(guān)鍵字13.2抽象類存在的問題:MoveForward方法僅僅是一個啞方法,它需要在子類中進(jìn)行覆蓋,如果放置了錯誤的方法而又有人調(diào)用,問題嚴(yán)重!19:publicvirtualvoidMoveForward()20:{21:Console.Write("Movingforward...");22:odometer+=1;23:Console.WriteLine("Odometerreading:{0}",odometer);24:}解決:使用抽象方法一個抽象方法只包含方法頭而且沒有實現(xiàn)代碼,它需要后續(xù)類來具體實現(xiàn)這一方法。當(dāng)一個類包含一個或多個抽象方法時,此類必須聲明為abstract。一個抽象類不能實例化,因為它包含沒有實現(xiàn)的方法。示例:AbstractMoveForward.cs
01:usingSystem;02:03:abstractclassCar04:{05:privateuintodometer=0;06:07:protecteduintOdometer08:{09:set10:{11:odometer=value;12:}13:get14:{15:returnodometer;16:}17:}18:19:publicabstractvoidMoveForward();20:}22:classRacingCar:Car23:{24:publicoverridevoidMoveForward()25:{26:Console.Write("Movingdangerouslyfastforward...");27:Odometer+=30;28:Console.WriteLine("Odometerinracingcar:{0}",Odometer);29:}30:}32:classFamilyCar:Car33:{34:publicoverridevoidMoveForward()35:{36:Console.Write("Movingslowlybutsafelyforward...");37:Odometer+=5;38:Console.WriteLine("Odometerinfamilycar:{0}",Odometer);39:}40:}42:classCarTester43:{44:publicstaticvoidMain()45:{46:RacingCarmyRacingCar=newRacingCar();47:FamilyCarmyFamilyCar=newFamilyCar();48:myRacingCar.MoveForward();49:myFamilyCar.MoveForward();50:}51:}SyntaxBox:AbstractMethodAbstract_method::=[<Method_modifiers>]abstract<Return_type>
<Method_identifier>([<Formal_parameter_list>]);Abstract_property_1::=
[<Property_modifiers>]abstract<Return_type><Property_identifier>{
[get;]
[set;]}Abstract_indexer_1::=
[<Indexer_modifiers>]abstract[<Return_type>]this[<Parameter_list>]{
[get;]
[set;]}Abstract_class::=
<Class_modifiers>abstract<Class_name>{
<Class_members>}說明:用關(guān)鍵字abstract聲明的抽象方法沒有方法體,在一對包括形式參數(shù)列表的圓括號后面有一個分號。抽象方法不能聲明為private、static、virtual抽象方法和抽象存取器為隱式的virtual抽象方法只能存在于抽象類中,但抽象類能包括非抽象方法抽象類不能實例化從一個包含抽象方法的類中派生一個類,派生類也成為抽象,除非覆蓋從基類中繼承的所有抽象方法并提供實現(xiàn)語句。在派生類中可以使用抽象方法來覆蓋虛方法,任何從此抽象類派生的類必須覆蓋這些抽象方法并提供新的實現(xiàn)語句,使之變成非抽象。9生活中的接口電腦主板上的PCI插槽的規(guī)范就類似于C#接口聲卡顯卡網(wǎng)卡每種卡的內(nèi)部結(jié)構(gòu)都不相同,可以把聲卡、網(wǎng)卡、顯卡都插在PCI插槽上,而不用擔(dān)心哪個插槽是專門插哪個卡的主板13.1理解接口關(guān)于多重繼承的爭議多重繼承可以讓類擁有多個基類當(dāng)兩個基類都包含一個信號相同但實現(xiàn)過程不同的方法或?qū)傩詴r發(fā)生的情況:moveforward、brandName、odometerC#禁止多重繼承而用另一種語言結(jié)構(gòu):接口來解決問題。13.1.1定義接口接口是表示一組函數(shù)成員而不實現(xiàn)成員的引用類型C#中使用interface定義接口注意:C#中建議接口名以大寫字母I開頭13.1.2實現(xiàn)接口要實現(xiàn)一個接口,需要聲明一個類或結(jié)構(gòu),讓它們從接口繼承,并實現(xiàn)接口指定的全部方法例如:interfaceILandBound{intNumberOfLegs();}然后可以在Horse類中實現(xiàn)該接口classHorse:ILandBound{...publicintNumberOfLegs(){return4;}}實現(xiàn)一個接口時,必須保證每個方法都完全匹配與它對應(yīng)的接口中的方法,規(guī)則如下:方法名和返回類型完全匹配所有參數(shù)(包括ref和out關(guān)鍵字)完全匹配使用接口名作為方法的前綴,稱之為顯式接口實現(xiàn),盡量使用顯式接口實現(xiàn)用于實現(xiàn)一個接口的所有方法都必須具有public可訪問性,但是,如果使用顯式接口實現(xiàn),則不應(yīng)該為方法添加訪問修飾符接口的定義和實現(xiàn)存在任何差異,類都無法編譯一個類可以在擴(kuò)展另一個類的同時實現(xiàn)一個接口下例將Horse定義成從Mammal繼承的一個類,同時實現(xiàn)了ILandBound接口interfaceILandBound{...}classMammal{...}classHorse:Mammal,ILandBound{...}13.1.3通過接口來引用一個類可以把一個變量定義成引用層次結(jié)構(gòu)中較高位置的一個類,然后用這個變量引用對象類似的,可以將一個變量定義成類所實現(xiàn)的接口,然后用這個變量引用對象例如:HorsemyHorse=newHorse(...);ILandBoundiMyHorse=myHorse;//legal通過接口來引用一個對象,是一項相當(dāng)有用的技術(shù)我們能由此定義方法,讓它獲得不同的類型作為參數(shù),只要類型實現(xiàn)了指定的接口intFindLandSpeed(ILandBoundlandBoundMammal){...}13.1.4使用多個接口一個類最多只能有一個基類,但可以實現(xiàn)數(shù)量無限的接口類必須實現(xiàn)它從它的所有接口繼承的所有方法例如:classHorse:Mammal,ILandBound,IGrazable{...}13.1.5顯式實現(xiàn)接口Horse類實現(xiàn)了ILandBound接口,但在Horse的NumberOfLegs方法中,沒有任何地方說它是ILandBound接口的一部分interfaceILandBound{intNumberOfLegs();}classHorse:ILandBound{...publicintNumberOfLegs(){return4;}}如果Horse類實現(xiàn)了多個接口,而多個接口指定了同名的方法,則會出現(xiàn)歧義例如:interfaceIJourney{intNumberOfLegs();}classHorse:ILandBound,IJourney{...publicintNumberOfLegs(){return4;}}C#中通過顯式實現(xiàn)接口解決這個問題為此,要在實現(xiàn)一個接口時,指明方法從屬于該接口classHorse:ILandBound,IJourney{...intILandBound.NumberOfLegs(){return4;}intIJourney.NumberOfLegs(){return3;}}注意:方法沒有用public標(biāo)記。如果方法是顯式接口實現(xiàn)的一部分,就不能為方法指定訪問修飾符,所以無法從類的外部訪問。如果方法在Horse類中可見,下述代碼無法確定Horsehorse=newHorse();...intlegs=horse.NumberOfLegs();應(yīng)該通過恰當(dāng)?shù)慕涌趤硪肏orse對象Horsehorse=newHorse();...IJourneyjourneyHorse=horse;intlegsInJourney=journeyHorse.NumberOfLegs();ILandBoundlandBoundHorse=horse;intlegsOnHorse=landBoundHorse.NumberOfLegs();abstractclass與interface抽象類(abstractclass)是一種特殊的類抽象方法只做聲明,而不包含實現(xiàn),可以看成是沒有實現(xiàn)體的虛方法抽象類不能被實例化,除此之外,具有類的其他特性抽象類可以但不是必須有抽象屬性和抽象方法,但是一旦有了抽象方法,就一定要把這個類聲明為抽象類具體派生類必須覆蓋基類的抽象方法抽象類可以派生自另一個抽象類,可以覆蓋基類的抽象方法也可以不覆蓋,如果不覆蓋,則其派生類必須覆蓋它們接口:是引用類型,類似于抽象類但又不同于抽象類不能被實例化只能包含實現(xiàn)的方法聲明成員可以包括方法、屬性、索引器和事件接口中不能包含常量、字段、構(gòu)造函數(shù)、析構(gòu)函數(shù)或靜態(tài)成員接口中的所有成員默認(rèn)為public,接口中不能有private成員派生類必須實現(xiàn)接口的所有成員一個類可以實現(xiàn)多個接口一個接口可以有多個父接口,實現(xiàn)該接口必須實現(xiàn)多有父接口中的所有成員抽象類和接口的共同點都可以被繼承都不能被實例化都可以包含方法聲明派生類必須實現(xiàn)未實現(xiàn)的方法抽象類和接口的區(qū)別抽象類是一個不完整的類,需要進(jìn)一步細(xì)化,而接口只是一個行為規(guī)范或規(guī)定,微軟的自定義接口總是后帶able字段,證明其是表述一類類“我能做…”.抽象類可以定義字段、屬性和方法實現(xiàn)。接口只能定義屬性、索引器、事件、和方法聲明,不能包含字段。抽象類更多的是定義在一系列緊密相關(guān)的類之間,而接口大多數(shù)是定義在關(guān)系疏松但都實現(xiàn)某一功能的類中。接口基本上不具備繼承的任何具體特點,它僅僅承諾了能夠調(diào)用的方法。接口可以被多重實現(xiàn),抽象類只能被單一繼承。即一個類一次可以實現(xiàn)若干個接口,但只能繼承一個父類。接口可以用于支持回調(diào),而繼承并不具備這個特點。抽象類不能被密封。抽象類實現(xiàn)的具體方法默認(rèn)為虛的,但實現(xiàn)接口類的接口方法卻默認(rèn)為非虛的,當(dāng)然也可以聲明為虛的。接口與非抽象類類似,抽象類也必須為在該類的基類表中列出接口的所有成員提供它自己的實現(xiàn)。但是,允許抽象類將接口方法映射到抽象方法上。如果抽象類實現(xiàn)接口,則可以把接口中的方法映射到抽象類中作為抽象方法而不必實現(xiàn),而在抽象類的子類中實現(xiàn)接口的方法。抽象類和接口的使用抽象類主要用于關(guān)系密切的對象;而接口用于為不相關(guān)的類提供通用功能如果要設(shè)計大的功能單元,則使用抽象類;如果要在組件的所有實現(xiàn)間提供通用的已實現(xiàn)功能,則使用抽象類。如果創(chuàng)建的功能將在大范圍的全異對象間使用,則使用接口。如果要設(shè)計小而簡練的功能塊,則使用接口。如果預(yù)計要創(chuàng)建組件的多個版本,則創(chuàng)建抽象類。抽象類提供簡單的方法來控制組件版本。好的接口定義應(yīng)該是具有專一功能性的,而不是多功能的,否則會造成接口的污染。如果一個類只是實現(xiàn)了這個接口中的一個功能,而不得不去實現(xiàn)接口的其他方法,那么就叫接口污染。盡量避免使用繼承來實現(xiàn)組件功能,而是使用黑箱復(fù)用,即對象組合。因為繼承的層次增多,造成最直接的后果就是當(dāng)你調(diào)用這個類群中的某一類時,就必須把它們?nèi)考虞d到棧中!后果可想而知。同時,有心的朋友可以留意到微軟在構(gòu)建一個類時,很多時候都用到了對象組合的方法。比如中的\Page類,有Server、Request等屬性,但其實它們都是某個類的對象。使用Page類的這個對象來調(diào)用另外類的方法和屬性,是非?;镜囊粋€設(shè)計原則。2413.1.6接口的限制不允許在接口中定義任何字段,即使是靜態(tài)字段。字段本質(zhì)上是類或結(jié)構(gòu)的一種實現(xiàn)細(xì)節(jié)不允許在接口中定義任何構(gòu)造器不允許在接口中定義任何析構(gòu)器不允許為任何方法指定訪問修飾符,接口中的所有方法都隱式為public不允許在接口中嵌套任何類型雖然一個接口能從另一個接口繼承,但不允許從結(jié)構(gòu)或者類中繼承一個接口。結(jié)構(gòu)或者類中含有實現(xiàn),假如允許接口從它們繼承,就會繼承一些實現(xiàn)。說明:接口標(biāo)示符習(xí)慣上以大寫I開頭,因為接口可以強(qiáng)迫類實現(xiàn)抽象成員讓類執(zhí)行額外的動作,所以類標(biāo)識符通常以able結(jié)尾??傊航涌诿枋鲂枰獙崿F(xiàn)的操作、屬性和事件,以及每個操作需要接受和返回的參數(shù)類型,但將操作的特定實現(xiàn)留給實現(xiàn)接口的類去完成。25接口的一個應(yīng)用在一個類層次中要實現(xiàn)多態(tài),必需具備一組有相同祖先的類如果我們想要劃分成組的類不具有相同的祖先呢?如果它們分布于整個程序的多個地方,甚至位于多個單獨的類層次中,情況如何??2627實現(xiàn)方法:publicinterfaceIDrawable{voidDrawYourself();}28示例程序:ComparableTimeSpans.cs01:usingSystem;02:03:publicinterfaceIComparable04:{05:intCompareTo(IComparablecomp);06:}07:08:publicclassTimeSpan:IComparable09:{10:privateuinttotalSeconds;11:12:publicTimeSpan()13:{14:totalSeconds=0;15:}16:17:publicTimeSpan(uintinitialSeconds)18:{19:totalSeconds=initialSeconds;20:}2922:publicuintSeconds23:{24:get25:{26:returntotalSeconds;27:}28:29:set30:{31:totalSeconds=value;32:}33:}34:35:publicintCompareTo(IComparablecomp)36:{37:TimeSpancompareTime=(TimeSpan)comp;38:39:if(totalSeconds>compareTime.Seconds)40:return1;41:elseif(compareTime.Seconds==totalSeconds)42:return0;43:else44:return-1;45:}46:}3048:classTester49:{50:publicstaticvoidMain()51:{52:TimeSpanmyTime=newTimeSpan(3450);53:TimeSpanworldRecord=newTimeSpan(1239);54:55:if(myTime.CompareTo(worldRecord)<0)56:Console.WriteLine("Mytimeisbelowtheworldrecord");57:elseif(myTime.CompareTo(worldRecord)==0)58:Console.WriteLine("Mytimeisthesameastheworldrecord");59:else60:Console.WriteLine("Ispentmoretimethantheworldrecordholder");61:}62:}Ispentmoretimethantheworldrecordholder31接口的另一個應(yīng)用示例排序的實現(xiàn):按姓名排序、分?jǐn)?shù)、院系一般性的實現(xiàn)過程:可重用于排序其他任何對象類型示例:BubbleSortAscening.cs3201://Sorttheelementsofanarrayinascendingorder02:publicstaticvoidBubbleSortAscending(int[]bubbles)03:{04:boolswapped=true;05:06:for(inti=0;swapped;i++)07:{08:swapped=false;09:for(intj=0;j<(bubbles.Length-(i+1));j++)10:{11:if(bubbles[j]>bubbles[j+1])12:{13:Swap(j,j+1,bubbles);14:swapped=true;15:}16:}17:}18:}19:20://Swaptwoelementsofanarray21:publicstaticvoidSwap(intfirst,intsecond,int[]arr)22:{23:inttemp;24:25:temp=arr[first];26:arr[first]=arr[second];27:arr[second]=temp;28:}33存在的問題:只能排序元素類型為int的數(shù)組思考:只有11行涉及到更換數(shù)組元素類型,其余代碼可以保持不變,使用替換代碼if(bubbles[j].CompareTo(bubbles[j+1])>0)實現(xiàn):將一般排序方法的形式參數(shù)聲明為Icomparable類型的數(shù)組,可以確定只有包含可比較對象的數(shù)組被傳遞給方法3401:usingSystem;02:03:publicinterfaceIComparable04:{05:intCompareTo(IComparablecomp);06:}07:08:publicclassTimeSpan:IComparable09:{10:privateuinttotalSeconds;11:12:publicTimeSpan()13:{14:totalSeconds=0;15:}16:17:publicTimeSpan(uintinitialSeconds)18:{19:totalSeconds=initialSeconds;20:}22:publicuintSeconds23:{24:get25:{26:returntotalSeconds;27:}28:29:set30:{31:totalSeconds=value;32:}33:}34:35:publicvirtualintCompareTo(IComparablecomp)36:{37:TimeSpancompareTime=(TimeSpan)comp;38:39:if(totalSeconds>compareTime.Seconds)40:return1;41:elseif(compareTime.Seconds==totalSeconds)42:return0;43:else44:return-1;45:}46:}3548:classSorter49:{50://Sortthecomparableelementsofanarrayinascendingorder51:publicstaticvoidBubbleSortAscending(IComparable[]bubbles)52:{53:boolswapped=true;55:for(inti=0;swapped;i++)56:{57:swapped=false;58:for(intj=0;j<(bubbles.Length-(i+1));j++)59:{60:if(bubbles[j].CompareTo(bubbles[j+1])>0)61:{62:Swap(j,j+1,bubbles);63:swapped=true;64:}65:}66:}67:}69://Swaptwoelementsofanarray70:publicstaticvoidSwap(intfirst,intsecond,IComparable[]arr)71:{72:IComparabletemp;74:temp=arr[first];75:arr[first]=arr[second];76:arr[second]=temp;77:}78:}3680:classT
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 手機(jī)品牌轉(zhuǎn)讓合同范例
- 小孩扶養(yǎng)權(quán)合同范例
- 醫(yī)院文化設(shè)計合同模板
- 崗位派遣合同模板
- 商業(yè)項目融資合同范例
- 室內(nèi)水電施工合同模板
- ktv 私人裝修合同范例
- 山皮石供應(yīng)合同范例
- 人員服務(wù)合同范例
- 快遞門店加盟合同范例
- 2025屆高考語文一輪復(fù)習(xí):二元思辨類作文思辨關(guān)系高階思維
- 華中科技大學(xué)青年長江學(xué)者答辯模板
- 國開(甘肅)2024年春《地域文化(專)》形考任務(wù)1-4終考答案
- 檔案整理及數(shù)字化服務(wù)方案(技術(shù)標(biāo) )
- 角的度量 華應(yīng)龍(課堂PPT)
- 公路銑刨機(jī)整機(jī)的設(shè)計含全套CAD圖紙
- 第三章非均相反應(yīng)
- 機(jī)器人學(xué)課程教學(xué)大綱
- 浙江世貿(mào)君瀾酒店集團(tuán)介紹
- GHTF—質(zhì)量管理體系--過程驗證指南中文版
- 鋁及鋁合金焊接作業(yè)指導(dǎo)書
評論
0/150
提交評論