




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第8章繼承與多態(tài)
本章將繼續(xù)深入介紹繼承和多態(tài)兩個重要思想以及在C#中的實現(xiàn),并詳細(xì)介紹由繼承和封裝而衍生出的抽象類、抽象函數(shù)、密封類、密封函數(shù)、運(yùn)算符重載、虛函數(shù)等重要的知識點。章節(jié)內(nèi)容8.1繼承的基礎(chǔ)知識8.2派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)8.3抽象類和抽象函數(shù)8.4密封類和密封方法8.5多態(tài)的基礎(chǔ)知識8.6虛方法8.7運(yùn)算符重載8.8接口8.9小結(jié)8.1.1簡單繼承C++中的多重繼承8.1.1簡單繼承C#為什么摒棄了多繼承?C#允許通過多個接口來變相地實現(xiàn)有控制的多繼承8.1.2使用繼承publicclassMobile //定義基類Mobile{publicMobile() //基類的構(gòu)造函數(shù)
{Console.WriteLine("Iamthebaseclass,Mobile.");}publicMobile(stringname) //基類的構(gòu)造函數(shù)
{Console.WriteLine("Hello,Mynameis"+name+"!");}publicvoidMemorySize(intsize){Console.WriteLine("MemorySizeis"+size+"Icanstorealot.");}}8.1.2使用繼承publicclassMoto:Mobile//定義派生類Moto{publicMoto() //派生類的構(gòu)造函數(shù)
{Console.WriteLine("Iamthederivedclass,Moto.");}}classProgram{staticvoidMain(string[]args){Motom=newMoto();m.MemorySize(100);Console.ReadLine();}8.1.3在派生類中使用基類的方法classCustomerAccount{publicdecimalCalculatePrice(){//實現(xiàn)代碼
return0.0M;}}classGoldAccount:CustomerAccount{publicdecimalCalculatePrice(){returnbase.CalculatePrice()*0.9M;}}8.2派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)構(gòu)造函數(shù)的調(diào)用順序為,先調(diào)用基類的構(gòu)造函數(shù),再調(diào)用派生類中的構(gòu)造函數(shù)體。因為基類沒有不帶參數(shù)的構(gòu)造函數(shù),所以即使是派生類的不帶參數(shù)的構(gòu)造函數(shù),也必須顯式調(diào)用基類的帶參數(shù)的構(gòu)造函數(shù),盡管該參數(shù)本身毫無意義。對基類構(gòu)造函數(shù)的調(diào)用必須使用base關(guān)鍵字,而不能像C++一樣用具體的類名代替。析構(gòu)函數(shù)的調(diào)用順序同構(gòu)造函數(shù)的調(diào)用順序完全相反。8.2派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)usingSystem;publicclassMobile{stringparentString;publicMobile(){Console.WriteLine("MobileConstructor.");}publicMobile(stringmyString){parentString=myString;Console.WriteLine(parentString);}publicvoidPrint(){Console.WriteLine("I'maMobileClass.");}}8.2派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)publicclassMoto:Mobile{
publicMoto():base("FromDerived"){Console.WriteLine("MotoConstructor.");}publicvoidPrint(){base.Print();Console.WriteLine("I'maMotoClass.");}publicstaticvoidMain(){Motomoto=newMoto();moto.Print();((Mobile)moto).Print();Console.ReadLine();}}程序運(yùn)行結(jié)果:FromDerivedMotoConstructor.I'maMobileClass.I'maMotoClass.I'maMobileClass.8.3抽象類和抽象函數(shù)抽象類表示一種抽象的概念,用于為其派生類提供一個公共接口。抽象類由abstract修飾符聲明。抽象類只能作為其他類的基類,而不能直接實例化,對抽象類使用new關(guān)鍵字會發(fā)生錯誤。抽象函數(shù)沒有實現(xiàn)代碼,而是由abstract修飾符聲明。抽象函數(shù)只提供函數(shù)名稱,具體實現(xiàn)交由繼承的派生類。可見,抽象函數(shù)同抽象類類似,也是虛擬的,但是這里的虛擬不需要而且絕對不能使用virtual關(guān)鍵字(即abstract和virtual修飾符不能一起使用),否則會產(chǎn)生語法錯誤。8.3抽象類和抽象函數(shù)抽象類可以包含抽象函數(shù),也可包含非抽象函數(shù),而非抽象類不能包含抽象函數(shù)。也就是說,包含了抽象函數(shù)的類一定是抽象類(假如抽象函數(shù)可以包含在非抽象類中,那么非抽象類實例調(diào)用沒有實現(xiàn)代碼的抽象函數(shù)時,顯然不合理)。當(dāng)從抽象類派生非抽象類時,非抽象類必須具體實現(xiàn)所繼承的所有抽象函數(shù),且必須使用override關(guān)鍵字重寫抽象類所定義的函數(shù)。抽象類可以被抽象類所繼承,結(jié)果可以仍是抽象類。抽象方法被實現(xiàn)后,不能更改原方法的修飾符。在C++中,對抽象函數(shù)有純虛函數(shù)一說;在C#中,僅使用抽象這個術(shù)語。8.3抽象類和抽象函數(shù)usingSystem;publicabstractclassPerson{publicabstractvoidSayHello();publicvoidAbout(){Console.WriteLine("AbstractDemo");}}publicclassStudent:Person{publicoverridevoidSayHello(){Console.WriteLine("SayHello");}}8.4密封類和密封方法當(dāng)類和方法被sealed修飾時,就成為了密封類和密封方法。對類來說,這表示不能繼承該類;對于方法來說,這表示不能重寫該方法。實際上,Java中也有類似的定義,但使用的關(guān)鍵字為final。對于密封類和密封方法的應(yīng)用場合通常是商業(yè)上保護(hù)版權(quán),防止被他人擴(kuò)展。8.4密封類和密封方法classBaseClass{publicvirtualvoidFinalMethod(){ //代碼}
}classMyClass:BaseClass{publicsealedoverridevoidFinalMethod(){//代碼} }classDerivedClass:MyClass{publicoverridevoidFinalMethod() //錯誤!
{//代碼}}8.5多態(tài)的基礎(chǔ)知識多態(tài)性(Polymorphism)是一個希臘單詞,指“同一個名稱,多種形態(tài)”。或者可以理解為,對同一個名稱,可以有不同的理解,有不同的反應(yīng)。例如,當(dāng)理發(fā)師聽到“cut”的時候會開始剪頭發(fā),演員聽到“cut”的時候會停止表演,醫(yī)生聽到“cut”的時候會在病人身上進(jìn)行手術(shù)。在面向?qū)ο缶幊讨?,多態(tài)是指調(diào)用同一個方法名,卻執(zhí)行不同的方法體。多態(tài)性是類為方法(這些方法以相同的名稱調(diào)用)提供不同實現(xiàn)方式的能力。多態(tài)性允許對類的某個方法進(jìn)行調(diào)用而無需考慮該方法所提供的特定實現(xiàn)。8.5多態(tài)的基礎(chǔ)知識在C#中,多態(tài)可以分為靜態(tài)多態(tài)和動態(tài)多態(tài)。靜態(tài)多態(tài)就是方法的重載(overload),也稱為靜態(tài)聯(lián)編,由編譯器在編譯期間確定真正執(zhí)行方法的地址。方法重載和運(yùn)算符重載(關(guān)于運(yùn)算符重載的介紹可參見本章8.7節(jié))都實現(xiàn)了編譯時的多態(tài)性。對于方法重載,需要:方法名必須相同。參數(shù)列表必須不相同(參數(shù)個數(shù)不同、參數(shù)類型不同或參數(shù)個數(shù)與類型都不相同)。和返回值類型無關(guān)。8.5多態(tài)的基礎(chǔ)知識動態(tài)多態(tài),也稱為動態(tài)聯(lián)編,指的是系統(tǒng)在編譯期間無法確定真正執(zhí)行方法的地址,在運(yùn)行期間由運(yùn)行時(CommonLanguageRuntime,CLR)根據(jù)虛方法表可動態(tài)計算出來。動態(tài)多態(tài)通過虛方法的重寫(override)來實現(xiàn)(關(guān)于虛方法的介紹可詳見本章8.6節(jié))。編譯時的多態(tài)性能夠提供運(yùn)行速度快的特點,而運(yùn)行時的多態(tài)性能夠提供高度靈活和抽象的特點。8.6虛方法對于類中的方法,若聲明時加上virtual修飾符,則稱該方法為虛方法,否則為非虛方法。和Java不同,Java中的方法默認(rèn)情況下都是虛方法;C#中類的方法默認(rèn)情況下都是非虛方法。在基類中把某個方法聲明為虛方法,在派生類中就可以通過在該方法名前加override關(guān)鍵字實現(xiàn)對基類中該方法的重寫虛方法和其他一般方法有較大的區(qū)別。一般方法在編譯時就靜態(tài)地編譯到了執(zhí)行文件中,其相對地址在程序運(yùn)行期間不發(fā)生變化;而虛方法在編譯期間不被靜態(tài)編譯,它的相對地址是不確定的,會根據(jù)運(yùn)行時期對象實例來動態(tài)判斷要調(diào)用的方法。8.6虛方法關(guān)于虛方法,需要注意:不僅僅只有方法可以虛擬,屬性、事件和索引器成員都可以虛擬,但字段不能是虛擬的。虛成員的訪問修飾符不能定義為私有。使用了virtual修飾符后,不允許再有static、abstract或override修飾符。使用了override修飾符后,不允許再有new、static或virtual修飾符。在派生類中重寫虛方法時,要求方法名稱、返回值類型、參數(shù)表中的參數(shù)個數(shù)、類型、順序、訪問修飾符都必須與基類中的虛方法完全一致。只有虛方法和抽象方法才能被重寫。8.6虛方法usingSystem;classA{publicvirtualvoidMethod(){Console.WriteLine("A.method");}}classB:A{publicnewvirtualvoidMethod(){Console.WriteLine("B.method");}}classC:B{publicoverridevoidMethod(){Console.WriteLine("C.method");}publicstaticvoidMain(){Aa=newA();Bb=newC();Ac=b;a.Method();b.Method();c.Method();Console.ReadLine();}}執(zhí)行結(jié)果:A.methodC.methodA.method8.6虛方法classC:B{publicoverridevoidMethod(){Console.WriteLine("C.method");}publicstaticvoidMain(){Aa=newA();Bb=newC();Ac=b;a.Method();b.Method();c.Method();Console.ReadLine();}}8.6虛方法關(guān)于虛方法,需要注意:不僅僅只有方法可以虛擬,屬性、事件和索引器成員都可以虛擬,但字段不能是虛擬的。虛成員的訪問修飾符不能定義為私有。使用了virtual修飾符后,不允許再有static、abstract或override修飾符。使用了override修飾符后,不允許再有new、static或virtual修飾符。在派生類中重寫虛方法時,要求方法名稱、返回值類型、參數(shù)表中的參數(shù)個數(shù)、類型、順序、訪問修飾符都必須與基類中的虛方法完全一致。只有虛方法和抽象方法才能被重寫。8.7運(yùn)算符重載運(yùn)算符重載是指允許用戶使用自定義的類型編寫表達(dá)式,允許用戶定義的類型與預(yù)定義的類型具有相同的功能,是對重載概念的一個重要補(bǔ)充和發(fā)展,它針對對象關(guān)系中的多元關(guān)系、四則運(yùn)算和關(guān)系運(yùn)算等常規(guī)運(yùn)算提供了重載支持。C#中定義運(yùn)算符重載的語法形式如下:
publicstatic返回值類型operator<operatorName>(<paramlist>)注意,運(yùn)算符重載的方法必須是public和static,operator是關(guān)鍵字,opertorName是要重載的運(yùn)算符。8.7運(yùn)算符重載classcomplex{privatedoublereal,imag;//復(fù)數(shù)實部和虛部
publiccomplex(doublea,intb){real=a;imag=b;}
publicstaticcomplexoperator++(complexc){c.real++;c.imag++;returnc;}publicvoidDisplay(){Console.WriteLine("complex.real={0},complex.imag={1}",real,imag);}
8.7運(yùn)算符重載
publicstaticcomplexoperator+(complexc1,complexc2){complexc=newcomplex(0,0);c.real=c1.real+c2.real;c.imag=c1.imag+c2.imag;returnc;}staticvoidMain(string[]args){complexc1=newcomplex(10,20);complexc2=newcomplex(30,40);c1=c1+c2;c1.Display();c1++;c1.Display();Console.ReadLine();}}代碼執(zhí)行結(jié)果:complex.real=40,complex.real=60complex.real=41,complex.real=618.7運(yùn)算符重載并非所有的運(yùn)算符都可以重載,運(yùn)算符重載規(guī)則如下:+、-、!、~、++、--、true、false,這些一元運(yùn)算符可被重載。+、-、*、/、%、&、|、^、<<、>>,這些二元運(yùn)算符可被重載。==、!=、<、>、<=、>=,這些關(guān)系運(yùn)算符可被重載。&&、||,這兩個條件運(yùn)算符不能被重載,但它們的值能夠被“&”和“|”評估,而這兩個運(yùn)算符可以被重載。數(shù)組運(yùn)算符([])不能被重載,可以定義索引器。轉(zhuǎn)換運(yùn)算符(())不能被重載,可以定義隱式類型轉(zhuǎn)換和顯式類型轉(zhuǎn)換運(yùn)算符。+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=,這些賦值運(yùn)算符不能被重載,但它們的值(如+=)會被“+”評估,而“+”可以被重載。=、.、?:、->、new、is、sizeof、typeof,這些運(yùn)算符不能被重載。8.8接口與類相同,接口也定義了一些方法、屬性、索引和事件。但與類不同的是,接口并不提供實現(xiàn),它只是一種約定,實現(xiàn)接口的類或結(jié)構(gòu)必須遵守該接口定義的約定。一個接口可以從多個基接口繼承,而一個類或結(jié)構(gòu)可以實現(xiàn)多個接口。當(dāng)類或結(jié)構(gòu)繼承接口時,意味著該類或結(jié)構(gòu)為該接口定義的所有成員提供實現(xiàn)。接口本身不提供類或結(jié)構(gòu)能夠以繼承基類功能的方式繼承的任何功能。但是,如果基類實現(xiàn)接口,派生類將繼承該實現(xiàn)。接口是體現(xiàn)面向?qū)ο缶幊趟枷雰?yōu)越性的一件利器。接口是為繼承而存在的,如果沒有繼承,那就自然不需要接口了。既然有繼承,就需要把可能被多個類所繼承的一些公共部分抽象出來,接口封裝的就是這些公共的行為規(guī)范(方法定義),類可以通過繼承多個接口來豐富自己的行為機(jī)制。但是,在C#中,類是不可以繼承多個類的,所以接口的變相多繼承作用就顯得靈活而至關(guān)重要。接口可以包含一個或多個成員,這些成員可以是方法、屬性、索引指示器或事件,但不能是常量、域、操作符、構(gòu)造函數(shù)或析構(gòu)函數(shù)。接口的成員是從基接口繼承的成員和由接口本身定義的成員。接口成員默認(rèn)訪問方式是public。接口成員定義不能包含任何修飾符,比如成員定義前不能加abstract、public、protected、internal、private、virtual、override或static修飾符。接口中不包含任何程序代碼,也不能有“{}”。接口不能包含構(gòu)造函數(shù)、析構(gòu)函數(shù)和靜態(tài)成員。接口不能直接實例化。8.8接口usingSystem;interfaceIProduct{intGetPrice(intid);voidShowName(stringname);}interfaceISize{intGetSize();}8.8接口classShoe:IProduct,ISize{publicintGetPrice(intid){if(id==1)return50;elsereturn100;}publicvoidShowName(stringname){Console.WriteLine(name);}publicintGetSize(){return35;}}8.8接口接口和第7章介紹的抽象類既有相似之處,也有不同之處。其相同之處如下。都不能被直接實例化,都可以通過繼承實現(xiàn)其抽象方法
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 鋼材供貨合同常用
- 金屬材料交易合同
- 法律咨詢在線服務(wù)平臺合同及免責(zé)聲明
- 交通基礎(chǔ)設(shè)施投資建設(shè)合同
- 2025-2030年中國電動套絲機(jī)板牙行業(yè)深度研究分析報告
- 2025-2030年中國上凝固輥行業(yè)深度研究分析報告
- 專業(yè)暖通工程合同承包商協(xié)議模板
- 農(nóng)業(yè)種植基地購銷合同范文
- 大數(shù)據(jù)分析應(yīng)用服務(wù)框架合同
- 連鎖超市加盟合同協(xié)議范本
- 2025年中考英語熱點話題預(yù)測-哪吒(含答案)
- 2024年環(huán)北部灣廣西水資源配置有限公司招聘考試真題
- 【2025新教材】教科版一年級科學(xué)下冊全冊教案【含反思】
- 2023-2024年演出經(jīng)紀(jì)人之演出經(jīng)紀(jì)實務(wù)考前沖刺模擬試卷附答案(研優(yōu)卷)
- 第16課《有為有不為 》課件-2024-2025學(xué)年統(tǒng)編版語文七年級下冊
- 律師執(zhí)業(yè)風(fēng)險防范研究-深度研究
- 2025年無錫職業(yè)技術(shù)學(xué)院高職單招職業(yè)適應(yīng)性測試近5年??及鎱⒖碱}庫含答案解析
- 2025年北京戲曲藝術(shù)職業(yè)學(xué)院高職單招數(shù)學(xué)歷年(2016-2024)頻考點試題含答案解析
- 2025年春新人教版語文一年級下冊教學(xué)課件 語文園地二
- 2025年青海西寧廣播電視臺招聘20人高頻重點提升(共500題)附帶答案詳解
- 2025年內(nèi)蒙古興安盟突泉縣選聘生態(tài)護(hù)林員450人歷年高頻重點提升(共500題)附帶答案詳解
評論
0/150
提交評論