版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第8章繼承與多態(tài)
本章將繼續(xù)深入介紹繼承和多態(tài)兩個(gè)重要思想以及在C#中的實(shí)現(xiàn),并詳細(xì)介紹由繼承和封裝而衍生出的抽象類、抽象函數(shù)、密封類、密封函數(shù)、運(yùn)算符重載、虛函數(shù)等重要的知識(shí)點(diǎn)。章節(jié)內(nèi)容8.1繼承的基礎(chǔ)知識(shí)8.2派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)8.3抽象類和抽象函數(shù)8.4密封類和密封方法8.5多態(tài)的基礎(chǔ)知識(shí)8.6虛方法8.7運(yùn)算符重載8.8接口8.9小結(jié)8.1.1簡(jiǎn)單繼承C++中的多重繼承8.1.1簡(jiǎn)單繼承C#為什么摒棄了多繼承?C#允許通過(guò)多個(gè)接口來(lái)變相地實(shí)現(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(){//實(shí)現(xiàn)代碼
return0.0M;}}classGoldAccount:CustomerAccount{publicdecimalCalculatePrice(){returnbase.CalculatePrice()*0.9M;}}8.2派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)構(gòu)造函數(shù)的調(diào)用順序?yàn)?,先調(diào)用基類的構(gòu)造函數(shù),再調(diào)用派生類中的構(gòu)造函數(shù)體。因?yàn)榛悰](méi)有不帶參數(shù)的構(gòu)造函數(shù),所以即使是派生類的不帶參數(shù)的構(gòu)造函數(shù),也必須顯式調(diào)用基類的帶參數(shù)的構(gòu)造函數(shù),盡管該參數(shù)本身毫無(wú)意義。對(duì)基類構(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ù)抽象類表示一種抽象的概念,用于為其派生類提供一個(gè)公共接口。抽象類由abstract修飾符聲明。抽象類只能作為其他類的基類,而不能直接實(shí)例化,對(duì)抽象類使用new關(guān)鍵字會(huì)發(fā)生錯(cuò)誤。抽象函數(shù)沒(méi)有實(shí)現(xiàn)代碼,而是由abstract修飾符聲明。抽象函數(shù)只提供函數(shù)名稱,具體實(shí)現(xiàn)交由繼承的派生類??梢?jiàn),抽象函數(shù)同抽象類類似,也是虛擬的,但是這里的虛擬不需要而且絕對(duì)不能使用virtual關(guān)鍵字(即abstract和virtual修飾符不能一起使用),否則會(huì)產(chǎn)生語(yǔ)法錯(cuò)誤。8.3抽象類和抽象函數(shù)抽象類可以包含抽象函數(shù),也可包含非抽象函數(shù),而非抽象類不能包含抽象函數(shù)。也就是說(shuō),包含了抽象函數(shù)的類一定是抽象類(假如抽象函數(shù)可以包含在非抽象類中,那么非抽象類實(shí)例調(diào)用沒(méi)有實(shí)現(xiàn)代碼的抽象函數(shù)時(shí),顯然不合理)。當(dāng)從抽象類派生非抽象類時(shí),非抽象類必須具體實(shí)現(xiàn)所繼承的所有抽象函數(shù),且必須使用override關(guān)鍵字重寫(xiě)抽象類所定義的函數(shù)。抽象類可以被抽象類所繼承,結(jié)果可以仍是抽象類。抽象方法被實(shí)現(xiàn)后,不能更改原方法的修飾符。在C++中,對(duì)抽象函數(shù)有純虛函數(shù)一說(shuō);在C#中,僅使用抽象這個(gè)術(shù)語(yǔ)。8.3抽象類和抽象函數(shù)usingSystem;publicabstractclassPerson{publicabstractvoidSayHello();publicvoidAbout(){Console.WriteLine("AbstractDemo");}}publicclassStudent:Person{publicoverridevoidSayHello(){Console.WriteLine("SayHello");}}8.4密封類和密封方法當(dāng)類和方法被sealed修飾時(shí),就成為了密封類和密封方法。對(duì)類來(lái)說(shuō),這表示不能繼承該類;對(duì)于方法來(lái)說(shuō),這表示不能重寫(xiě)該方法。實(shí)際上,Java中也有類似的定義,但使用的關(guān)鍵字為final。對(duì)于密封類和密封方法的應(yīng)用場(chǎng)合通常是商業(yè)上保護(hù)版權(quán),防止被他人擴(kuò)展。8.4密封類和密封方法classBaseClass{publicvirtualvoidFinalMethod(){ //代碼}
}classMyClass:BaseClass{publicsealedoverridevoidFinalMethod(){//代碼} }classDerivedClass:MyClass{publicoverridevoidFinalMethod() //錯(cuò)誤!
{//代碼}}8.5多態(tài)的基礎(chǔ)知識(shí)多態(tài)性(Polymorphism)是一個(gè)希臘單詞,指“同一個(gè)名稱,多種形態(tài)”。或者可以理解為,對(duì)同一個(gè)名稱,可以有不同的理解,有不同的反應(yīng)。例如,當(dāng)理發(fā)師聽(tīng)到“cut”的時(shí)候會(huì)開(kāi)始剪頭發(fā),演員聽(tīng)到“cut”的時(shí)候會(huì)停止表演,醫(yī)生聽(tīng)到“cut”的時(shí)候會(huì)在病人身上進(jìn)行手術(shù)。在面向?qū)ο缶幊讨校鄳B(tài)是指調(diào)用同一個(gè)方法名,卻執(zhí)行不同的方法體。多態(tài)性是類為方法(這些方法以相同的名稱調(diào)用)提供不同實(shí)現(xiàn)方式的能力。多態(tài)性允許對(duì)類的某個(gè)方法進(jìn)行調(diào)用而無(wú)需考慮該方法所提供的特定實(shí)現(xiàn)。8.5多態(tài)的基礎(chǔ)知識(shí)在C#中,多態(tài)可以分為靜態(tài)多態(tài)和動(dòng)態(tài)多態(tài)。靜態(tài)多態(tài)就是方法的重載(overload),也稱為靜態(tài)聯(lián)編,由編譯器在編譯期間確定真正執(zhí)行方法的地址。方法重載和運(yùn)算符重載(關(guān)于運(yùn)算符重載的介紹可參見(jiàn)本章8.7節(jié))都實(shí)現(xiàn)了編譯時(shí)的多態(tài)性。對(duì)于方法重載,需要:方法名必須相同。參數(shù)列表必須不相同(參數(shù)個(gè)數(shù)不同、參數(shù)類型不同或參數(shù)個(gè)數(shù)與類型都不相同)。和返回值類型無(wú)關(guān)。8.5多態(tài)的基礎(chǔ)知識(shí)動(dòng)態(tài)多態(tài),也稱為動(dòng)態(tài)聯(lián)編,指的是系統(tǒng)在編譯期間無(wú)法確定真正執(zhí)行方法的地址,在運(yùn)行期間由運(yùn)行時(shí)(CommonLanguageRuntime,CLR)根據(jù)虛方法表可動(dòng)態(tài)計(jì)算出來(lái)。動(dòng)態(tài)多態(tài)通過(guò)虛方法的重寫(xiě)(override)來(lái)實(shí)現(xiàn)(關(guān)于虛方法的介紹可詳見(jiàn)本章8.6節(jié))。編譯時(shí)的多態(tài)性能夠提供運(yùn)行速度快的特點(diǎn),而運(yùn)行時(shí)的多態(tài)性能夠提供高度靈活和抽象的特點(diǎn)。8.6虛方法對(duì)于類中的方法,若聲明時(shí)加上virtual修飾符,則稱該方法為虛方法,否則為非虛方法。和Java不同,Java中的方法默認(rèn)情況下都是虛方法;C#中類的方法默認(rèn)情況下都是非虛方法。在基類中把某個(gè)方法聲明為虛方法,在派生類中就可以通過(guò)在該方法名前加override關(guān)鍵字實(shí)現(xiàn)對(duì)基類中該方法的重寫(xiě)虛方法和其他一般方法有較大的區(qū)別。一般方法在編譯時(shí)就靜態(tài)地編譯到了執(zhí)行文件中,其相對(duì)地址在程序運(yùn)行期間不發(fā)生變化;而虛方法在編譯期間不被靜態(tài)編譯,它的相對(duì)地址是不確定的,會(huì)根據(jù)運(yùn)行時(shí)期對(duì)象實(shí)例來(lái)動(dòng)態(tài)判斷要調(diào)用的方法。8.6虛方法關(guān)于虛方法,需要注意:不僅僅只有方法可以虛擬,屬性、事件和索引器成員都可以虛擬,但字段不能是虛擬的。虛成員的訪問(wèn)修飾符不能定義為私有。使用了virtual修飾符后,不允許再有static、abstract或override修飾符。使用了override修飾符后,不允許再有new、static或virtual修飾符。在派生類中重寫(xiě)虛方法時(shí),要求方法名稱、返回值類型、參數(shù)表中的參數(shù)個(gè)數(shù)、類型、順序、訪問(wèn)修飾符都必須與基類中的虛方法完全一致。只有虛方法和抽象方法才能被重寫(xiě)。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)于虛方法,需要注意:不僅僅只有方法可以虛擬,屬性、事件和索引器成員都可以虛擬,但字段不能是虛擬的。虛成員的訪問(wèn)修飾符不能定義為私有。使用了virtual修飾符后,不允許再有static、abstract或override修飾符。使用了override修飾符后,不允許再有new、static或virtual修飾符。在派生類中重寫(xiě)虛方法時(shí),要求方法名稱、返回值類型、參數(shù)表中的參數(shù)個(gè)數(shù)、類型、順序、訪問(wèn)修飾符都必須與基類中的虛方法完全一致。只有虛方法和抽象方法才能被重寫(xiě)。8.7運(yùn)算符重載運(yùn)算符重載是指允許用戶使用自定義的類型編寫(xiě)表達(dá)式,允許用戶定義的類型與預(yù)定義的類型具有相同的功能,是對(duì)重載概念的一個(gè)重要補(bǔ)充和發(fā)展,它針對(duì)對(duì)象關(guān)系中的多元關(guān)系、四則運(yùn)算和關(guān)系運(yùn)算等常規(guī)運(yùn)算提供了重載支持。C#中定義運(yùn)算符重載的語(yǔ)法形式如下:
publicstatic返回值類型operator<operatorName>(<paramlist>)注意,運(yùn)算符重載的方法必須是public和static,operator是關(guān)鍵字,opertorName是要重載的運(yùn)算符。8.7運(yùn)算符重載classcomplex{privatedoublereal,imag;//復(fù)數(shù)實(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)算符可被重載。&&、||,這兩個(gè)條件運(yùn)算符不能被重載,但它們的值能夠被“&”和“|”評(píng)估,而這兩個(gè)運(yùn)算符可以被重載。數(shù)組運(yùn)算符([])不能被重載,可以定義索引器。轉(zhuǎn)換運(yùn)算符(())不能被重載,可以定義隱式類型轉(zhuǎn)換和顯式類型轉(zhuǎn)換運(yùn)算符。+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=,這些賦值運(yùn)算符不能被重載,但它們的值(如+=)會(huì)被“+”評(píng)估,而“+”可以被重載。=、.、?:、->、new、is、sizeof、typeof,這些運(yùn)算符不能被重載。8.8接口與類相同,接口也定義了一些方法、屬性、索引和事件。但與類不同的是,接口并不提供實(shí)現(xiàn),它只是一種約定,實(shí)現(xiàn)接口的類或結(jié)構(gòu)必須遵守該接口定義的約定。一個(gè)接口可以從多個(gè)基接口繼承,而一個(gè)類或結(jié)構(gòu)可以實(shí)現(xiàn)多個(gè)接口。當(dāng)類或結(jié)構(gòu)繼承接口時(shí),意味著該類或結(jié)構(gòu)為該接口定義的所有成員提供實(shí)現(xiàn)。接口本身不提供類或結(jié)構(gòu)能夠以繼承基類功能的方式繼承的任何功能。但是,如果基類實(shí)現(xiàn)接口,派生類將繼承該實(shí)現(xiàn)。接口是體現(xiàn)面向?qū)ο缶幊趟枷雰?yōu)越性的一件利器。接口是為繼承而存在的,如果沒(méi)有繼承,那就自然不需要接口了。既然有繼承,就需要把可能被多個(gè)類所繼承的一些公共部分抽象出來(lái),接口封裝的就是這些公共的行為規(guī)范(方法定義),類可以通過(guò)繼承多個(gè)接口來(lái)豐富自己的行為機(jī)制。但是,在C#中,類是不可以繼承多個(gè)類的,所以接口的變相多繼承作用就顯得靈活而至關(guān)重要。接口可以包含一個(gè)或多個(gè)成員,這些成員可以是方法、屬性、索引指示器或事件,但不能是常量、域、操作符、構(gòu)造函數(shù)或析構(gòu)函數(shù)。接口的成員是從基接口繼承的成員和由接口本身定義的成員。接口成員默認(rèn)訪問(wèn)方式是public。接口成員定義不能包含任何修飾符,比如成員定義前不能加abstract、public、protected、internal、private、virtual、override或static修飾符。接口中不包含任何程序代碼,也不能有“{}”。接口不能包含構(gòu)造函數(shù)、析構(gòu)函數(shù)和靜態(tài)成員。接口不能直接實(shí)例化。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章介紹的抽象類既有相似之處,也有不同之處。其相同之處如下。都不能被直接實(shí)例化,都可以通過(guò)繼承實(shí)現(xiàn)其抽象方法
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 純英文早教課堂課程設(shè)計(jì)
- 2025年度建筑工程設(shè)計(jì)變更三方協(xié)議書(shū)3篇
- 2024年度藝術(shù)品買(mǎi)賣(mài)合同性質(zhì)與藝術(shù)品評(píng)估協(xié)議3篇
- 2024明源云不動(dòng)產(chǎn)經(jīng)營(yíng)租賃合同模板3篇
- 三亞2025安置房銷(xiāo)售合同模板3篇
- 2025年桉樹(shù)種植與木材深加工項(xiàng)目合同范本3篇
- 2025版歷史建筑保護(hù)監(jiān)理合同延期補(bǔ)充協(xié)議范本3篇
- 二零二五年體育賽事贊助與廣告權(quán)益合同2篇
- 2024民間小額借貸合同范本參考3篇
- 萬(wàn)兆工廠試點(diǎn)項(xiàng)目的規(guī)劃設(shè)計(jì)與實(shí)施路徑
- 2024版人才引進(jìn)住房租賃補(bǔ)貼協(xié)議3篇
- 川藏鐵路勘察報(bào)告范文
- 新零售智慧零售門(mén)店解決方案
- 小學(xué)一年級(jí)數(shù)學(xué)20以內(nèi)的口算題(可直接打印A4)
- 上海黃浦區(qū)2025屆物理高一第一學(xué)期期末質(zhì)量跟蹤監(jiān)視模擬試題含解析
- 肺結(jié)核課件教學(xué)課件
- 規(guī)劃設(shè)計(jì)行業(yè)數(shù)字化轉(zhuǎn)型趨勢(shì)
- 工程力學(xué)智慧樹(shù)知到期末考試答案2024年
- 七年級(jí)生物試卷分析3篇
- 30題紀(jì)檢監(jiān)察位崗位常見(jiàn)面試問(wèn)題含HR問(wèn)題考察點(diǎn)及參考回答
- 本質(zhì)安全理論綜述研究
評(píng)論
0/150
提交評(píng)論