面向?qū)ο缶幊蹋豪^承.ppt_第1頁(yè)
面向?qū)ο缶幊蹋豪^承.ppt_第2頁(yè)
面向?qū)ο缶幊蹋豪^承.ppt_第3頁(yè)
面向?qū)ο缶幊蹋豪^承.ppt_第4頁(yè)
面向?qū)ο缶幊蹋豪^承.ppt_第5頁(yè)
已閱讀5頁(yè),還剩13頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、C#高級(jí)編程:繼承,Kavass Zhu 2011/03/24,課程重點(diǎn),實(shí)現(xiàn)繼承和接口繼承 多重繼承 調(diào)用函數(shù)的基類(lèi)版本 虛方法、隱藏方法和方法的重寫(xiě) 派生類(lèi)的構(gòu)造函數(shù) 抽象類(lèi)和抽象函數(shù) 接口的定義和實(shí)現(xiàn),1.繼承的類(lèi)型,繼承的類(lèi)型主要包括兩種:實(shí)現(xiàn)繼承和接口繼承。 實(shí)現(xiàn)繼承:表示一個(gè)類(lèi)型派生于一個(gè)基類(lèi)型,擁有該基類(lèi)型的所有成員字段和函數(shù),在實(shí)現(xiàn)繼承中,派生類(lèi)型的每個(gè)函數(shù)采用基類(lèi)型的實(shí)現(xiàn)代碼,除非在派生類(lèi)型的定義中指定重寫(xiě)該函數(shù)的實(shí)現(xiàn)代碼。在需要給現(xiàn)有類(lèi)型添加功能,或許多相關(guān)的類(lèi)型共享一個(gè)重要的公共功能時(shí),這種類(lèi)型的繼承是非常有效的。 接口繼承:表示一個(gè)類(lèi)型只繼承類(lèi)函數(shù)的簽名,沒(méi)有繼承任何實(shí)

2、現(xiàn)代碼。在需要指定該類(lèi)型具有某些可用的特性時(shí),最好使用這種類(lèi)型的繼承。接口繼承常常被看做提供了一種契約:讓類(lèi)型派生于接口,來(lái)保證為客戶提供某個(gè)功能。 在C#中,既有實(shí)現(xiàn)繼承,也有接口繼承。他們沒(méi)有強(qiáng)弱之分,因?yàn)檫@兩種繼承都完全內(nèi)置于語(yǔ)言中,因此很容易為不同的情形選擇最好的體系結(jié)構(gòu)。C#不支持多重實(shí)現(xiàn)繼承,但支持多重接口繼承。 結(jié)構(gòu)不支持實(shí)現(xiàn)繼承,但結(jié)構(gòu)自動(dòng)派生于System.ValueType,并且支持接口繼承。 結(jié)構(gòu)總是派生于System.ValueType,還可以派生于任意多個(gè)接口 類(lèi)總是派生于用戶選擇的另一個(gè)類(lèi),還可以派生于任意多個(gè)接口,如果要聲明一個(gè)類(lèi)派生于另一個(gè)類(lèi),可以使用下面的語(yǔ)法

3、: class MyClass:MyBaseClass 如果類(lèi)或結(jié)構(gòu)也派生于接口,則用逗號(hào)分隔開(kāi)基類(lèi)和接口: class MyClass:MyBaseClass,IInterface1,IInterface2 對(duì)于結(jié)構(gòu)語(yǔ)法如下: struct MyStruct:IInterface1,IInterface2 如果在類(lèi)定義中沒(méi)有指定基類(lèi),C#編譯器就假定System.Object是基類(lèi)。因此下面兩段代碼是相同的: class MyClass:Object class MyClass C#至此object關(guān)鍵字,它用作System.Object 類(lèi)的假名,所以也可以寫(xiě)成: clsss MyClas

4、s:object ,2.實(shí)現(xiàn)繼承,把一個(gè)基類(lèi)函數(shù)聲明為virtual,該函數(shù)就可以在任何派生類(lèi)中重寫(xiě)。 Class MyBaseClass Public virtual string VirtualMethod() return “this is virtual method”; 也可以把屬性聲明為virtual。對(duì)于虛屬性或重寫(xiě)屬性,語(yǔ)法與非虛屬性是相同的,但是要在定義中加上關(guān)鍵字virtual,其語(yǔ)法如下所示: public virtual string Name Get return _name; Set _name=value; ,2.1 虛方法,C#中虛函數(shù)的概念與標(biāo)準(zhǔn)OOP概念相同

5、,可以在派生類(lèi)中重寫(xiě)虛函數(shù)。在調(diào)用方法時(shí),會(huì)調(diào)用對(duì)象類(lèi)型合適的方法。C#中,函數(shù)默認(rèn)不是徐牛的,但可以顯示的聲明為virtual。在派生類(lèi)中需要重寫(xiě)虛函數(shù)要使用override關(guān)鍵字顯式聲明: class MyClass:BaseClass Public override string VirtualMethod() return “this is override method”; 如果在派生類(lèi)中沒(méi)有使用override關(guān)鍵字,并且派生類(lèi)的函數(shù)名稱和簽名與基類(lèi)中的函數(shù)和簽名一致時(shí),將會(huì)產(chǎn)生編譯警告。 成員字段和靜態(tài)函數(shù)不能聲明為virtual。因?yàn)樗粚?duì)類(lèi)中的實(shí)例函數(shù)成員有意義。虛方法的聲明

6、和重寫(xiě)不能是private。,如果簽名相同的方法在基類(lèi)和派生類(lèi)中都進(jìn)行了聲明,但該方法沒(méi)有聲明為virtual和override,派生類(lèi)方法就會(huì)隱藏基類(lèi)方法。 在C#中隱藏方法有顯式隱藏和隱式隱藏兩種,一般建議用顯式隱藏。隱式隱藏會(huì)收到編譯器的警告信息。 class BaseClass Public void Test() 顯式隱藏 class MyClass:BaseClass Public new void Test() 隱式隱藏 class MyClass:baseClass public void Test() ,2.2 隱藏方法,C#有一種特殊的語(yǔ)法用于從派生類(lèi)中調(diào)用方法的基類(lèi)版本:

7、base.MethodName()。語(yǔ)法如下: class BaseClass Public virtual string getName() return “kavass”; Class MyClass:BaseClass public override string getName() return base.getName()+” zhu”; 這時(shí)MyClass的實(shí)例調(diào)用getName()方法是將得到的是基類(lèi)的getName的方法加“ zhu”以后的字符串,2.3 調(diào)用函數(shù)的基類(lèi)版本,C#允許把類(lèi)和函數(shù)聲明為abstract,抽象類(lèi)不能實(shí)例化,而抽象函數(shù)沒(méi)有執(zhí)行代碼,必須在非抽象的派生類(lèi)

8、中重寫(xiě)。如果類(lèi)包含抽象函數(shù),該類(lèi)將也是抽象的,也必須聲明為抽象的: abstract class BaseClass Public abstract string getName(); Class MyClass:BaseClass Public override string getName() Return “kavass”; 抽象函數(shù)不能聲明為private,在派生類(lèi)中重寫(xiě)時(shí)也不能是private。抽象函數(shù)不能有實(shí)現(xiàn)的主體。,2.4 抽象類(lèi)和抽象函數(shù),C#允許把類(lèi)和方法聲明為sealed。對(duì)于類(lèi)來(lái)說(shuō),這表示不能繼承該類(lèi);對(duì)于方法來(lái)說(shuō),這表示不能重寫(xiě)該方法。 在把類(lèi)或方法標(biāo)記為sealed

9、時(shí),最可能的情形是:如果要對(duì)庫(kù)、類(lèi)或自己編寫(xiě)的其他類(lèi)進(jìn)行操作,則重寫(xiě)某些功能會(huì)導(dǎo)致錯(cuò)誤。也可以因商業(yè)原因把類(lèi)或方法標(biāo)記為sealed,以防止第三方以違法注冊(cè)協(xié)議的方式擴(kuò)展該類(lèi)。但一般情況下,在把類(lèi)或標(biāo)記為sealed時(shí)要小心,因?yàn)檫@么做會(huì)嚴(yán)重限制他的使用。即使不希望它能繼承一個(gè)類(lèi)或重寫(xiě)類(lèi)的某個(gè)成員,仍有可能在將來(lái)的某個(gè)時(shí)刻,有人會(huì)遇到我們沒(méi)有預(yù)料的情形。.NET基類(lèi)庫(kù)大量使用了密封類(lèi),使希望從這些類(lèi)中派生出自己的類(lèi)的第三方開(kāi)發(fā)人員無(wú)法訪問(wèn)這些類(lèi)。 在方法上使用sealed關(guān)鍵字是沒(méi)有意義的,除非該方法本身是某個(gè)基類(lèi)上另一個(gè)方法的重寫(xiě)形式。如果定義一個(gè)新方法,但不想讓別人重寫(xiě)它,首先就不要把它聲

10、明為virtual。但如果要重寫(xiě)某個(gè)基類(lèi)方法,sealed關(guān)鍵字就提供了一種方式,可以確保為方法提供的重寫(xiě)代碼是最終的代碼。其他人不能再重寫(xiě)它,2.5 密封類(lèi)和密封方法,假定沒(méi)有為類(lèi)定義任何顯式的構(gòu)造函數(shù),這樣編譯器就會(huì)為所有的類(lèi)提供默認(rèn)的構(gòu)造函數(shù),在后臺(tái)會(huì)進(jìn)行許多操作,編譯器可以很好的解決層次結(jié)構(gòu)中的所有問(wèn)題,每個(gè)類(lèi)中的字段都會(huì)初始化為默認(rèn)值。但在添加一個(gè)我們自己的構(gòu)造函數(shù)后,就要通過(guò)派生類(lèi)的層次結(jié)構(gòu)高效地控制構(gòu)造過(guò)程,因此必須確保構(gòu)造過(guò)程順利進(jìn)行,不要出現(xiàn)不能按照層次結(jié)構(gòu)進(jìn)行構(gòu)造的問(wèn)題。 為什么派生類(lèi)會(huì)有某些特殊的問(wèn)題,原因是在創(chuàng)建派生類(lèi)的實(shí)例時(shí),實(shí)際上會(huì)有多個(gè)構(gòu)造函數(shù)起作用。要實(shí)例化的類(lèi)

11、的構(gòu)造函數(shù)本身不能初始化類(lèi),還必須調(diào)用基類(lèi)中的構(gòu)造函數(shù)。這就是為什么要通過(guò)層次結(jié)構(gòu)進(jìn)行構(gòu)造的原因。 構(gòu)造函數(shù)的調(diào)用順序是先調(diào)用System.Object,再按照層次結(jié)構(gòu)由上向下進(jìn)行,直到到達(dá)編譯器要實(shí)例化的類(lèi)為至。還要注意在這個(gè)過(guò)程中,每個(gè)構(gòu)造函數(shù)都初始化自己的類(lèi)中的字段。在開(kāi)始添加自己的構(gòu)造函數(shù)時(shí),也應(yīng)盡可能遵循這個(gè)規(guī)則。 class BaseClass private string name; Class MyClass:BaseClass Private int age; ,2.6 派生類(lèi)的構(gòu)造函數(shù),注意構(gòu)造函數(shù)的執(zhí)行順序?;?lèi)的構(gòu)造函數(shù)總是最先調(diào)用,也就是說(shuō),派生類(lèi)的構(gòu)造函數(shù)可以在執(zhí)行

12、過(guò)程中調(diào)用基類(lèi)方法、屬性和其他成員,因?yàn)榛?lèi)已經(jīng)構(gòu)造出來(lái),其字段也初始化了。 1.在層次結(jié)構(gòu)中添加無(wú)參數(shù)的構(gòu)造函數(shù) 首先討論最簡(jiǎn)單的情況,在層次結(jié)構(gòu)中用一個(gè)無(wú)參數(shù)的構(gòu)造函數(shù)來(lái)替換默認(rèn)的構(gòu)造函數(shù)后,看看會(huì)發(fā)生什么情況。假如要把每個(gè)人的名字初始化為,而不是null引用,如下所示: Class BaseClass Private string name; Public BaseClass():base() Name=“”; Class Myclass:BaseClass prinvate int age; 上面的代碼運(yùn)行正常,在MyClass實(shí)例化以后name將被出示化為。 在定制構(gòu)造函數(shù)中,在執(zhí)行

13、基類(lèi)構(gòu)造函數(shù)前,添加一個(gè)多基類(lèi)構(gòu)造函數(shù)的調(diào)用,,使用的語(yǔ)法與我們以前學(xué)過(guò)的重載構(gòu)造函數(shù)的語(yǔ)法相同。唯一的區(qū)別是將this換成base,這表示的是調(diào)用基類(lèi)的構(gòu)造函數(shù),而不是調(diào)用類(lèi)本省的構(gòu)造函數(shù)。在base關(guān)鍵字后面的圓括號(hào)中沒(méi)有參數(shù),這是非常重要的,因?yàn)闆](méi)有給基類(lèi)構(gòu)造函數(shù)傳遞參數(shù),所以編譯器會(huì)調(diào)用無(wú)參數(shù)的構(gòu)造函數(shù),其結(jié)果是編譯器會(huì)自動(dòng)調(diào)用System.Object的構(gòu)造函數(shù)。 上面的代碼中的Base()可以省略,將會(huì)調(diào)用默認(rèn)的基類(lèi)的構(gòu)造函數(shù)。 2.在層次結(jié)構(gòu)中添加帶參數(shù)的構(gòu)造函數(shù) Class BaseClass Private string name; Public BaseClass(stri

14、ng name) =name; Class Myclass:BaseClass prinvate int age; 代碼是否運(yùn)行正常?,編譯器試圖為派生類(lèi)創(chuàng)建默認(rèn)構(gòu)造函數(shù)時(shí),會(huì)產(chǎn)生一個(gè)編譯錯(cuò)誤,因?yàn)榫幾g器為子類(lèi)生成默認(rèn)的構(gòu)造函數(shù)會(huì)調(diào)用父類(lèi)的無(wú)參數(shù)構(gòu)造函數(shù),但父類(lèi)沒(méi)有這樣的構(gòu)造函數(shù),因此需要為子類(lèi)提供一個(gè)構(gòu)造函數(shù),來(lái)避免這個(gè)錯(cuò)誤: class BaseClass private string name; public BaseClass(string name) = name; class MyClass : BaseClass private int ag

15、e; public MyClass() : base(null) 子類(lèi)在實(shí)例化的時(shí)候先會(huì)去調(diào)用父類(lèi)的有參數(shù)的構(gòu)造函數(shù),帶父類(lèi)的構(gòu)造函數(shù)執(zhí)行完畢,將繼續(xù)執(zhí)行子類(lèi)的構(gòu)造函數(shù)。,聲明接口在語(yǔ)法上與聲明抽象類(lèi)完全相同,但不允許提供接口中任何成員的執(zhí)行方式。一般情況下,接口中只能包含方法、屬性、索引器和事件的聲明。 接口不能實(shí)例化,它只能包含其成員的簽名。接口不能有構(gòu)造函數(shù)或字段。接口定義不允許包含運(yùn)算符重載,這不是因?yàn)槁暶魉麄冊(cè)谠瓌t上有什么問(wèn)題,而是因?yàn)榻涌谕ǔJ枪财跫s,包含運(yùn)算符重載會(huì)一起一些與其他.NET語(yǔ)言不兼容得問(wèn)題。在接口定義中還不允許聲明成員上的修飾符,因?yàn)榻涌诘某蓡T總是公共的,不能聲明

16、為虛擬和靜態(tài)的。 interface ITest void test(); ,3 接口,首先我們定義一個(gè)接口: interface IBank void PayIn(decimal amount); void Withdraw(decimal amount); decimal Balance get; 實(shí)現(xiàn)一個(gè)接口: class BuildBank : IBank private decimal balance; public void PayIn(decimal amount) balance+=amount;,3.1 定義和實(shí)現(xiàn)接口,Console.WriteLine(建設(shè)銀行提示:存款成

17、功,存入0!,amount); public bool Withdraw(decimal amount) bool result ; if (balance amount) result = false; Console.WriteLine(建設(shè)銀行提示:帳戶余額不足,取款失敗!); else balance -= amount; result = true; Console.WriteLine(建設(shè)銀行提示:取款成功,請(qǐng)收取0現(xiàn)金!,amount); return result; ,class Program static void Main(string args) BuildBank buil = new BuildBank(); buil.PayIn(1000); buil.Withdraw(1200); buil.Withdraw(100); Console.WriteLine(buil.ToString(); IBank bank = new Bu

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論