類(lèi)型、方法與繼承_第1頁(yè)
類(lèi)型、方法與繼承_第2頁(yè)
類(lèi)型、方法與繼承_第3頁(yè)
類(lèi)型、方法與繼承_第4頁(yè)
類(lèi)型、方法與繼承_第5頁(yè)
已閱讀5頁(yè),還剩35頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、類(lèi)型、方法與繼承類(lèi)型簡(jiǎn)述 n在.NET代碼中,我們可以很方便的創(chuàng)建各種類(lèi)型,一個(gè)簡(jiǎn)單的數(shù)據(jù)模型、復(fù)雜的聚合對(duì)象類(lèi)型、或是對(duì)客觀世界實(shí)體的抽象 。n類(lèi) (class) 是最基礎(chǔ)的 C# 類(lèi)型 ,支持繼承與多態(tài)。一個(gè)c# 類(lèi)Class主要包含兩種基本成員: n狀態(tài)(字段、常量、屬性等)狀態(tài)(字段、常量、屬性等)n操作(方法、事件、索引器、構(gòu)造函數(shù)等)操作(方法、事件、索引器、構(gòu)造函數(shù)等)n利用創(chuàng)建的類(lèi)型(或者系統(tǒng)提供的),可以很容易的創(chuàng)建對(duì)象的實(shí)例。使用 new 運(yùn)算符創(chuàng)建,該運(yùn)算符為新的實(shí)例分配內(nèi)存,調(diào)用構(gòu)造函數(shù)初始化該實(shí)例,并返回對(duì)該實(shí)例的引用,如下面的語(yǔ)法形式: n = new (構(gòu)造函數(shù)的

2、參數(shù)) n創(chuàng)建后的實(shí)例對(duì)象,是一個(gè)存儲(chǔ)在內(nèi)存上(在線程?;蛲泄芏焉希┑囊粋€(gè)對(duì)象 ,可以創(chuàng)造實(shí)例的類(lèi)型在內(nèi)存中又是一個(gè)什么樣的存在 ?Type Objectn就是類(lèi)型對(duì)象(就是類(lèi)型對(duì)象(Type Object) nint a = 123; / 創(chuàng)建int類(lèi)型實(shí)例a nint b = 20; / 創(chuàng)建int類(lèi)型實(shí)例b nvar atype = a.GetType(); / 獲取對(duì)象實(shí)例a的類(lèi)型nType var btype = b.GetType(); / 獲取對(duì)象實(shí)例b的類(lèi)型Type nConsole.WriteLine(System.Object.Equals(atype,btype); /輸

3、出:True nConsole.WriteLine(System.Object.ReferenceEquals(atype, btype); /輸出:True n任何對(duì)象都有一個(gè)GetType()方法(基類(lèi)System.Object提供的),該方法返回一個(gè)對(duì)象的類(lèi)型,類(lèi)型上面包含了對(duì)象內(nèi)部的詳細(xì)信息,如字段、屬性、方法、基類(lèi)、事件等等(通過(guò)反射可以獲?。?。在上面的代碼中兩個(gè)不同的int變量的類(lèi)型(int.GetType())是同一個(gè)Type,說(shuō)明int在內(nèi)存中有唯一一個(gè)(類(lèi)似靜態(tài)的)Systen.Int32類(lèi)型。 n上面獲取到的Type對(duì)象(Systen.Int32)就是一個(gè)類(lèi)型對(duì)象,她同其他

4、引用類(lèi)型一樣,也是一個(gè)引用對(duì)象,這個(gè)對(duì)象中存儲(chǔ)了int32類(lèi)型的所有信息(類(lèi)型的所有元數(shù)據(jù)信息)。 n每一個(gè)類(lèi)型(如System.Int32)在內(nèi)存中都會(huì)有一個(gè)唯一的類(lèi)型對(duì)象,通過(guò)(int)a.GetType()可以獲取該對(duì)象; n類(lèi)型對(duì)象(Object Type)存儲(chǔ)在內(nèi)存中一個(gè)獨(dú)立的區(qū)域,叫加載堆(Load Heap),加載堆是在進(jìn)程創(chuàng)建的時(shí)候創(chuàng)建的,不受GC垃圾回收管制,因此類(lèi)型對(duì)象一經(jīng)創(chuàng)建就不會(huì)被釋放的,他的生命周期從AppDomain創(chuàng)建到結(jié)束; n前問(wèn)說(shuō)過(guò),每個(gè)引用對(duì)象都包含兩個(gè)附加成員:TypeHandle和同步索引塊,其中TypeHandle就指向該對(duì)象對(duì)應(yīng)的類(lèi)型對(duì)象;n類(lèi)型對(duì)

5、象的加載由class loader負(fù)責(zé),在第一次使用前加載;n類(lèi)型中的靜態(tài)字段就是存儲(chǔ)在這里的(加載堆上的類(lèi)型對(duì)象),所以說(shuō)靜態(tài)字段是全局的,而且不會(huì)釋放;方法表n類(lèi)型對(duì)象內(nèi)部的主要的結(jié)構(gòu)是怎么樣的呢?其中最重要的就是方法表方法表,包含了是類(lèi)型內(nèi)部的所有方法入口。npublic class A public virtual void Print() Console.WriteLine(A); npublic class B1 : A public override void Print() Console.WriteLine(B1); npublic class B2 : A public n

6、ew void Print() Console.WriteLine(B2); nB1 b1 = new B1(); B2 b2 = new B2(); n內(nèi)部結(jié)構(gòu)圖方法表的加載方法表的加載 n方法表的加載時(shí)父類(lèi)在前子類(lèi)在后的,首先加載的是固定的4個(gè)來(lái)自System.Object的虛方法:ToString, Equals, GetHashCode, and Finalize;n然后加載父類(lèi)A的虛方法;n加載自己的方法;n最后是構(gòu)造方法:靜態(tài)構(gòu)造函數(shù).cctor(),對(duì)象構(gòu)造函數(shù).ctor()n方法的調(diào)用方法的調(diào)用:當(dāng)執(zhí)行代碼b1.Print()時(shí)(此處只關(guān)注方法調(diào)用,忽略方法的繼承等因素),通過(guò)

7、b1的TypeHandel找到對(duì)應(yīng)類(lèi)型對(duì)象,然后找到方法表槽,然后是對(duì)應(yīng)的IL代碼,第一次執(zhí)行的時(shí)候,JIT編譯器需要把IL代碼編譯為本地機(jī)器碼,第一次執(zhí)行完成后機(jī)器碼會(huì)保留,下一次執(zhí)行就不需要JIT編譯了。這也是為什么說(shuō).NET程序啟動(dòng)需要預(yù)熱的原因。 繼承本質(zhì)繼承本質(zhì)n方法表的創(chuàng)建過(guò)程是從父類(lèi)到子類(lèi)自上而下的,這是.NET中繼承的很好體現(xiàn),當(dāng)發(fā)現(xiàn)有覆寫(xiě)當(dāng)發(fā)現(xiàn)有覆寫(xiě)父類(lèi)虛方法會(huì)覆蓋同名的父方法父類(lèi)虛方法會(huì)覆蓋同名的父方法,所有類(lèi)型的加載都會(huì)遞歸到System.Object類(lèi) 。n繼承是可傳遞的,子類(lèi)是對(duì)父類(lèi)的擴(kuò)展,必須繼承父類(lèi)方法,同時(shí)可以添加新方法。n子類(lèi)可以調(diào)用父類(lèi)方法和字段,而父類(lèi)不能

8、調(diào)用子類(lèi)方法和字段。 n子類(lèi)不光繼承父類(lèi)的公有成員,也繼承了私有成員,只是不可直接訪問(wèn)。nnew關(guān)鍵字在虛方法繼承中的阻斷作用,中斷某一虛方法的繼承傳遞。n因此類(lèi)型B1、B2的類(lèi)型對(duì)象進(jìn)一步的結(jié)構(gòu)示意圖如下:n在加載B1類(lèi)型對(duì)象時(shí),當(dāng)加載override B1.Print(“B1”)時(shí),發(fā)現(xiàn)有覆寫(xiě)override的方法,會(huì)覆蓋父類(lèi)的同名虛方法Print(“A”),就是下面的示意圖,簡(jiǎn)單來(lái)說(shuō)就是在B1中Print只有一個(gè)實(shí)現(xiàn)版本;n加載B2類(lèi)型對(duì)象時(shí),new關(guān)鍵字表示要隱藏基類(lèi)的虛方法,此時(shí)B2中的Print(“B2”)就不是虛方法了,她是B2中的新方法了,簡(jiǎn)單來(lái)說(shuō)就是在B2類(lèi)型對(duì)象中Print

9、有2個(gè)實(shí)現(xiàn)版本;nB2 b2 = new B2(); B1 b1 = new B1(); n b1.Print(); b2.Print(); /按預(yù)期應(yīng)該輸出 B1、B2 nA ab1 = new B1(); A ab2 = new B2(); ab1.Print(); ab2.Print(); /這里應(yīng)該輸出什么呢? 用基類(lèi)(A)和用本身B1聲明到底有什么區(qū)別: n無(wú)論用什么做引用聲明,哪怕是object,等號(hào)右邊的 = new 類(lèi)型()都是沒(méi)有區(qū)別的,也就說(shuō)說(shuō)對(duì)象的創(chuàng)建不受影響的,b1和ab1對(duì)象在內(nèi)存結(jié)構(gòu)上是一致的;n他們的的差別就在引用指針的類(lèi)型不同,這種不同在編碼中智能提示就直觀的反

10、應(yīng)出來(lái)了,在實(shí)際方法調(diào)用上也與引用指針類(lèi)型有直接關(guān)系;n綜合來(lái)說(shuō),不同引用指針類(lèi)型對(duì)于對(duì)象的創(chuàng)建(new操作)不影響;但對(duì)于對(duì)象的使用(如方法調(diào)用)有影響,這一點(diǎn)在上面代碼的執(zhí)行結(jié)果中體現(xiàn)出來(lái)了!n對(duì)于虛方法的調(diào)用,在IL中都是使用指令callvirt,該指令主要意思就是具體的方法在運(yùn)行時(shí)動(dòng)態(tài)確定的: ncallvirt使用虛擬調(diào)度,也就是根據(jù)引用類(lèi)型的動(dòng)態(tài)類(lèi)型來(lái)調(diào)度方法,callvirt指令根據(jù)引用變量指向的對(duì)象類(lèi)型來(lái)調(diào)用方法,在運(yùn)行時(shí)動(dòng)態(tài)綁定,主要用于調(diào)用虛方法。 n不同的類(lèi)型指針在虛擬方法表中有不同的附加信息作為標(biāo)志來(lái)區(qū)別其訪問(wèn)的地址區(qū)域,稱(chēng)為offset。不同類(lèi)型的指針只能在其特定地址

11、區(qū)域內(nèi)進(jìn)行執(zhí)行。編譯器在方法調(diào)用時(shí)還有一個(gè)原則: n執(zhí)行就近原則:對(duì)于同名字段或者方法,編譯器是按照其順序查找來(lái)引用的,也就是首先訪問(wèn)離它創(chuàng)建最近的字段或者方法。 nA ab1 = new B1();A ab2 = new B2(); ab1.Print(); ab2.Print(); /這里應(yīng)該輸出什么呢? n當(dāng)執(zhí)行以下代碼時(shí),引用指針類(lèi)型都為父類(lèi)A,引用指針類(lèi)型的offset指向父類(lèi),如下圖,按照就近查找執(zhí)行原則,輸出B1、A 繼承n抽象類(lèi):n抽象類(lèi)提供多個(gè)派生類(lèi)共享基類(lèi)的公共定義,抽象類(lèi)提供多個(gè)派生類(lèi)共享基類(lèi)的公共定義,它既可以提供抽象方法,也可以提供非抽象方它既可以提供抽象方法,也可以

12、提供非抽象方法。抽象類(lèi)不能實(shí)例化,必須通過(guò)繼承由派生法。抽象類(lèi)不能實(shí)例化,必須通過(guò)繼承由派生類(lèi)實(shí)現(xiàn)其抽象方法,因此對(duì)抽象類(lèi)不能使用類(lèi)實(shí)現(xiàn)其抽象方法,因此對(duì)抽象類(lèi)不能使用new關(guān)鍵字,也不能被密封。關(guān)鍵字,也不能被密封。 n抽象類(lèi)使用Abstract聲明,抽象方法也是用Abstract標(biāo)示;n抽象類(lèi)不能被實(shí)例化;n抽象方法必須定義在抽象類(lèi)中;n抽象類(lèi)可以繼承一個(gè)抽象類(lèi);n抽象類(lèi)不能被密封(不能使用sealed);n同類(lèi)Class一樣,只支持單繼承;npublic abstract class AbstractUser public int Age get; set; public abstrac

13、t void SetName(string name); 接口n接口簡(jiǎn)單理解就是一種規(guī)范、契約,使得實(shí)現(xiàn)接口簡(jiǎn)單理解就是一種規(guī)范、契約,使得實(shí)現(xiàn)接口的類(lèi)或結(jié)構(gòu)在形式上保持一致。實(shí)現(xiàn)接口接口的類(lèi)或結(jié)構(gòu)在形式上保持一致。實(shí)現(xiàn)接口的類(lèi)或結(jié)構(gòu)必須實(shí)現(xiàn)接口定義中所有接口成員,的類(lèi)或結(jié)構(gòu)必須實(shí)現(xiàn)接口定義中所有接口成員,以及該接口從其他接口中繼承的所有接口成員。以及該接口從其他接口中繼承的所有接口成員。 基本特點(diǎn):n接口使用interface聲明;n接口類(lèi)似于抽象基類(lèi),不能直接實(shí)例化接口;n接口中的方法都是抽象方法,不能有實(shí)現(xiàn)代碼,實(shí)現(xiàn)接口的任何非抽象類(lèi)型都必須實(shí)現(xiàn)接口的所有成員:n接口成員是自動(dòng)公開(kāi)的,且不能包含任何訪問(wèn)修飾符。n接口自身可從多個(gè)接口繼承,類(lèi)和結(jié)構(gòu)可繼承多

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論