已閱讀5頁(yè),還剩13頁(yè)未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
深入淺出.NET中關(guān)鍵字-base和this雖然訪問關(guān)鍵字不是很難理解的話題,我們還是有可以深入討論的地方來理清思路。還是老辦法,我的問題先列出來,您是否做好了準(zhǔn)備。 1.是否可以在靜態(tài)方法中使用base和this,為什么? 2.base常用于哪些方面?this常用于哪些方面? 3.可以base訪問基類的一切成員嗎? 4.如果有三層或者更多繼承,那么最下級(jí)派生類的base指向那一層呢?例如.NET體系中,如果以base訪問,則應(yīng)該是直接父類實(shí)例呢,還是最高層類實(shí)例呢? 5.以base和this應(yīng)用于構(gòu)造函數(shù)時(shí),繼承類對(duì)象實(shí)例化的執(zhí)行順序如何? 2. 基本概念base和this在C#中被歸于訪問關(guān)鍵字,顧名思義,就是用于實(shí)現(xiàn)繼承機(jī)制的訪問操作,來滿足對(duì)對(duì)象成員的訪問,從而為多態(tài)機(jī)制提供更加靈活的處理方式。 2.1 base關(guān)鍵字其用于在派生類中實(shí)現(xiàn)對(duì)基類公有或者受保護(hù)成員的訪問,但是只局限在構(gòu)造函數(shù)、實(shí)例方法和實(shí)例屬性訪問器中,MSDN中小結(jié)的具體功能包括:調(diào)用基類上已被其他方法重寫的方法。 指定創(chuàng)建派生類實(shí)例時(shí)應(yīng)調(diào)用的基類構(gòu)造函數(shù)。 2.2 this關(guān)鍵字其用于引用類的當(dāng)前實(shí)例,也包括繼承而來的方法,通常可以隱藏this,MSDN中的小結(jié)功能主要包括:限定被相似的名稱隱藏的成員 將對(duì)象作為參數(shù)傳遞到其他方法 聲明索引器 3. 深入淺出3.1 示例為上下面以一個(gè)小示例來綜合的說明,base和this在訪問操作中的應(yīng)用,從而對(duì)其有個(gè)概要了解,更詳細(xì)的規(guī)則和深入我們接著闡述。本示例沒有完全的設(shè)計(jì)概念,主要用來闡述base和this關(guān)鍵字的使用要點(diǎn)和難點(diǎn)闡述,具體的如下: using System;namespace A.My_Must_net public class Action public static void ToRun(Vehicle vehicle) Console.WriteLine(0 is running., vehicle.ToString(); public class Vehicle private string name; private int speed; private string array = new string10; public Vehicle() /限定被相似的名稱隱藏的成員 public Vehicle(string name, int speed) = name; this.speed = speed; public virtual void ShowResult() Console.WriteLine(The top speed of 0 is 1., name, speed); public void Run() /傳遞當(dāng)前實(shí)例參數(shù) Action.ToRun(this); /聲明索引器,必須為this,這樣就可以像數(shù)組一樣來索引對(duì)象 public string thisint param getreturn arrayparam; setarrayparam = value; public class Car: Vehicle /派生類和基類通信,以base實(shí)現(xiàn),基類首先被調(diào)用 /指定創(chuàng)建派生類實(shí)例時(shí)應(yīng)調(diào)用的基類構(gòu)造函數(shù) public Car() : base(Car, 200) public Car(string name, int speed) : this() public override void ShowResult() /調(diào)用基類上已被其他方法重寫的方法 base.ShowResult(); Console.WriteLine(Its a cars result.); public class Audi : Car public Audi() : base(Audi, 300) public Audi(string name, int speed) : this() public override void ShowResult() /由三層繼承可以看出,base只能繼承其直接基類成員 base.ShowResult(); base.Run(); Console.WriteLine(Its audis result.); public class BaseThisTester public static void Main(string args) Audi audi = new Audi(); audi1 = A6; audi2 = A8; Console.WriteLine(audi1); audi.Run(); audi.ShowResult(); 3.2 示例說明上面的示例基本包括了base和this使用的所有基本功能演示,具體的說明可以從注釋中得到解釋,下面的說明是對(duì)注釋的進(jìn)一步闡述和補(bǔ)充,來說明在應(yīng)用方面的幾個(gè)要點(diǎn):1.base常用于,在派生類對(duì)象初始化時(shí)和基類進(jìn)行通信。 2.base可以訪問基類的公有成員和受保護(hù)成員,私有成員是不可訪問的。 3.this指代類對(duì)象本身,用于訪問本類的所有常量、字段、屬性和方法成員,而且不管訪問元素是任何訪問級(jí)別。因?yàn)?,this僅僅局限于對(duì)象內(nèi)部,對(duì)象外部是無(wú)法看到的,這就是this的基本思想。另外,靜態(tài)成員不是對(duì)象的一部分,因此不能在靜態(tài)方法中引用this。 4.在多層繼承中,base可以指向的父類的方法有兩種情況:一是有重載存在的情況下,base將指向直接繼承的父類成員的方法,例如Audi類中的ShowResult方法中,使用base訪問的將是Car.ShowResult()方法,而不能訪問Vehicle.ShowResult()方法;而是沒有重載存在的情況下,base可以指向任何上級(jí)父類的公有或者受保護(hù)方法,例如Audi類中,可以使用base訪問基類Vehicle.Run()方法。這些我們可以使用ILDasm.exe,從IL代碼中得到答案。 .method public hidebysig virtual instance void ShowResult() cil managed / 代碼大小 27 (0x1b) .maxstack 8 IL_0000: nop IL_0001: ldarg.0 /base調(diào)用父類成員 IL_0002: call instance void A.My_Must_net.Car:ShowResult() IL_0007: nop IL_0008: ldarg.0 /base調(diào)用父類成員,因?yàn)闆]有實(shí)現(xiàn)Car.Run(),所以指向更高級(jí)父類 IL_0009: call instance void A.My_Must_net.Vehicle:Run() IL_000e: nop IL_000f: ldstr Its audis result. IL_0014: call void mscorlibSystem.Console:WriteLine(string) IL_0019: nop IL_001a: ret / end of method Audi:ShowResult3.3 深入剖析 如果有三次或者更多繼承,那么最下級(jí)派生類的base指向那一層呢?例如.NET體系中,如果以base訪問,則應(yīng)該是直接父類實(shí)例呢,還是最高層類實(shí)例呢?首先我們有必要了解類創(chuàng)建過程中的實(shí)例化順序,才能進(jìn)一步了解base機(jī)制的詳細(xì)執(zhí)行過程。一般來說,實(shí)例化過程首先要先實(shí)例化其基類,并且依此類推,一直到實(shí)例化System.Object為止。因此,類實(shí)例化,總是從調(diào)用System.Object.Object()開始。因此示例中的類Audi的實(shí)例化過程大概可以小結(jié)為以下順序執(zhí)行,詳細(xì)可以參考示例代碼分析。 1.執(zhí)行System.Object.Object(); 2.執(zhí)行Vehicle.Vehicle(string name, int speed); 3.執(zhí)行Car.Car(); 4.執(zhí)行Car.Car(string name, int speed); 5.執(zhí)行Audi.Audi(); 6.執(zhí)行Audi.Audi(string name, int speed)。 我們?cè)诔浞至私馄鋵?shí)例化順序的基礎(chǔ)上就可以順利的把握base和this在作用于構(gòu)造函數(shù)時(shí)的執(zhí)行情況,并進(jìn)一步了解其基本功能細(xì)節(jié)。下面更重要的分析則是,以ILDASM.exe工具為基礎(chǔ)來分析IL反編譯代碼,以便更深層次的了解執(zhí)行在base和this背后的應(yīng)用實(shí)質(zhì),只有這樣我們才能說對(duì)技術(shù)有了基本的剖析。Main方法的執(zhí)行情況為:.method public hidebysig static void Main(string args) cil managed .entrypoint / 代碼大小 61 (0x3d) .maxstack 3 .locals init (class A.My_Must_net.Audi V_0) IL_0000: nop /使用newobj指令創(chuàng)建新的對(duì)象,并調(diào)用構(gòu)造函數(shù)初始化 IL_0001: newobj instance void A.My_Must_net.Audi:.ctor() IL_0006: stloc.0 IL_0007: ldloc.0 IL_0008: ldc.i4.1 IL_0009: ldstr A6 IL_000e: callvirt instance void A.My_Must_net.Vehicle:set_Item(int32, string) IL_0013: nop IL_0014: ldloc.0 IL_0015: ldc.i4.2 IL_0016: ldstr A8 IL_001b: callvirt instance void A.My_Must_net.Vehicle:set_Item(int32, string) IL_0020: nop IL_0021: ldloc.0 IL_0022: ldc.i4.1 IL_0023: callvirt instance string A.My_Must_net.Vehicle:get_Item(int32) IL_0028: call void mscorlibSystem.Console:WriteLine(string) IL_002d: nop IL_002e: ldloc.0 IL_002f: callvirt instance void A.My_Must_net.Vehicle:Run() IL_0034: nop IL_0035: ldloc.0 /base.ShowResult最終調(diào)用的是最高級(jí)父類Vehicle的方法, /而不是直接父類Car.ShowResult()方法,這是應(yīng)該關(guān)注的 IL_0036: callvirt instance void A.My_Must_net.Vehicle:ShowResult() IL_003b: nop IL_003c: ret / end of method BaseThisTester:Main因此,對(duì)重寫父類方法,最終指向了最高級(jí)父類的方法成員。4. 通用規(guī)則盡量少用或者不用base和this。除了決議子類的名稱沖突和在一個(gè)構(gòu)造函數(shù)中調(diào)用其他的構(gòu)造函數(shù)之外,base和this的使用容易引起不必要的結(jié)果。 在靜態(tài)成員中使用base和this都是不允許的。原因是,base和this訪問的都是類的實(shí)例,也就是對(duì)象,而靜態(tài)成員只能由類來訪問,不能由對(duì)象來訪問。 base是為了實(shí)現(xiàn)多態(tài)而設(shè)計(jì)的。 使用this或base關(guān)鍵字只能指定一個(gè)構(gòu)造函數(shù),也就是說不可同時(shí)將this和base作用在一個(gè)構(gòu)造函數(shù)上。 簡(jiǎn)單的來說,base用于在派生類中訪問重寫的基類成員;而this用于訪問本類的成員,當(dāng)然也包括繼承而來公有和保護(hù)成員。 除了base,訪問基類成員的另外一種方式是:顯示的類型轉(zhuǎn)換來實(shí)現(xiàn)。只是該方法不能為靜態(tài)方法。 5. 結(jié)論base和this關(guān)鍵字,不是特別難于理解的內(nèi)容,本文之所以將其作為系列的主題,除了對(duì)其應(yīng)用規(guī)則做以小結(jié)之外,更重要的是在關(guān)注其執(zhí)行細(xì)節(jié)的基礎(chǔ)上,對(duì)語(yǔ)言背景建立更清晰的把握和分析,這些才是學(xué)習(xí)和技術(shù)應(yīng)用的根本所在,也是.NET技術(shù)框架中本質(zhì)訴求。對(duì)學(xué)習(xí)者來說,只有從本質(zhì)上來把握概念,才能在變化非凡的應(yīng)用中,一眼找到答案。 深入淺出關(guān)鍵字-把new說透2007年06月12日 星期二 09:39你真的理解了new嗎?如果是,那請(qǐng)不要浪費(fèi)時(shí)間,如果不是,那請(qǐng)繼續(xù)本文的循序之旅。 下面幾個(gè) 問題可以大概的考察你對(duì)new的掌握,開篇之前,希望大家做個(gè)檢驗(yàn),如果通過了,直接關(guān)掉本頁(yè)即可。如果沒有通過,希望本文的闡述能幫你找出答案。new一個(gè)class對(duì)象和new一個(gè)struct或者enum有什么不同? new在.NET中有幾個(gè)用途,除了創(chuàng)建對(duì)象實(shí)例,還能做什么? new運(yùn)算符,可以重載嗎? 范型中,new有什么作用? new一個(gè)繼承下來的方法和override一個(gè)繼承方法有何區(qū)別? int i和int i = new int()有什么不同? 2. 基本概念一般說來,new關(guān)鍵字在.NET中用于以下幾個(gè)場(chǎng)合,這是MSDN的典型解釋:作為運(yùn)算符, 用于創(chuàng)建對(duì)象和調(diào)用構(gòu)造函數(shù)。 本文的重點(diǎn)內(nèi)容,本文在下一節(jié)來重點(diǎn)考慮。作為修飾符,用于向基類成員隱藏繼承成員。 作為修飾符,基本的規(guī)則可以總結(jié)為:實(shí)現(xiàn)派生類中隱藏方法,則基類方法必須定義為virtual;new作為修飾符,實(shí)現(xiàn)隱藏基類成員時(shí),不可和override共存,原因是這兩者語(yǔ)義相斥:new用于實(shí)現(xiàn)創(chuàng)建一個(gè)新成員,同時(shí)隱藏基類的同名成員;而override用于實(shí)現(xiàn)對(duì)基類成員的擴(kuò)展。另外,如果在子類中隱藏了基類的數(shù)據(jù)成員,那么對(duì)基類原數(shù)據(jù)成員的訪問,可以通過base修飾符來完成。例如: new作為修飾符using System;namespace A.My_Must_net class Number public static int i = 123; public void ShowInfo() Console.WriteLine(base class-); public virtual void ShowNumber() Console.WriteLine(i.ToString(); class IntNumber : Number new public static int i = 456; public new virtual void ShowInfo() Console.WriteLine(Derived class-); public override void ShowNumber() Console.WriteLine(Base number is 0, Number.i.ToString(); Console.WriteLine(New number is 0, i.ToString(); class Tester public static void Main(string args) Number num = new Number(); num.ShowNumber(); IntNumber intNum = new IntNumber(); intNum.ShowNumber(); Number number = new IntNumber(); /究竟調(diào)用了誰(shuí)? number.ShowInfo(); /究竟調(diào)用了誰(shuí)? number.ShowNumber(); 作為約束,用于在泛型聲明中約束可能用作類型參數(shù)的參數(shù)的類型。 MSDN中的定義是:new 約束指定泛型類聲明中的任何類型參數(shù)都必須有公共的無(wú)參數(shù)構(gòu)造函數(shù)。當(dāng)泛型類創(chuàng)建類型的新實(shí)例時(shí),將此約束應(yīng)用于類型參數(shù)。注意:new作為約束和其他約束共存時(shí),必須在最后指定。其定義方式為: class Genericer where T : new() public T GetItem() return new T(); 實(shí)現(xiàn)方式為: class MyCls private string _name; public MyCls() _name = Emma; class MyGenericTester public static void Main(string args) Genericer MyGen = new Genericer(); Console.WriteLine(MyGen.GetItem().Name); 使用new實(shí)現(xiàn)多態(tài)。 這不是我熟悉的話題,詳細(xì)的內(nèi)容可以參見 多態(tài)與 new C#,這里有較詳細(xì)的論述。 3. 深入淺出作為修飾符和約束的情況,不是很難理解的話題,正如我們看到本文開篇提出的問題,也大多集中在new作為運(yùn)算符的情況,因此我們研究的重點(diǎn)就是揭開new作為運(yùn)算符的前世今生。Jeffrey Richter在其著作中,極力推薦讀者使用ILDASM工具查看IL語(yǔ)言細(xì)節(jié),從而提高對(duì).NET的深入探究,在我認(rèn)為這真是一條不錯(cuò)的建議,也給了自己很多提高的空間挖掘。因此,以下是本人的一點(diǎn)建議,我將在后續(xù)的系列中,關(guān)于學(xué)習(xí)方法論的討論中深入探討,這里只是順便小議,希望有益于大家。1 不斷的學(xué)習(xí)代碼;2 經(jīng)??纯碔L語(yǔ)言的運(yùn)行細(xì)節(jié),對(duì)于提供.NET的認(rèn)識(shí)非常有效。 文歸正題,new運(yùn)算符用于返回一個(gè)引用,指向系統(tǒng)分配的托管堆的內(nèi)存地址。因此,在此我們以Reflector工具,來了解以下new操作符執(zhí)行的背后,隱藏著什么玄機(jī)。 首先我們實(shí)現(xiàn)一段最簡(jiǎn)單的代碼,然后分析其元數(shù)據(jù)的實(shí)現(xiàn)細(xì)節(jié),來探求new在創(chuàng)建對(duì)象時(shí)到做了什么? new作為運(yùn)算符using System;namespace A.My_Must_net class MyClass private int _id; public MyClass(int id) _id = id; struct MyStruct private string _name; public MyStruct(string name) _name = name; class NewReflecting public static void Main(string args) int i; int j = new int(); MyClass mClass = new MyClass(123); MyStruct mStruct = new MyStruct(My Struct); 使用Reflector工具反編譯產(chǎn)生的IL代碼如下為: IL元數(shù)據(jù)分析.method public hidebysig static void Main(string args) cil managed .entrypoint .maxstack 2 .locals init ( 0 int32 num, 1 int32 num2, 2 class A.My_Must_net._05_new.MyClass class2, 3 valuetype A.My_Must_net._05_new.MyStruct struct2) L_0000: nop /初始化j為0 L_0001: ldc.i4.0 L_0002: stloc.1 /使用newobj指令創(chuàng)建新的對(duì)象,并調(diào)用構(gòu)造函數(shù)以0x76(123的16進(jìn)制)初始化 L_0003: ldc.i4.s 0x7b L_0005: newobj instance void A.My_Must_net._05_new.MyClass:.ctor(int32) L_000a: stloc.2 /加載“My Struct” L_000b: ldloca.s struct2 L_000d: ldstr My Struct /調(diào)用構(gòu)造函數(shù)執(zhí)行初始化 L_0012: call instance void A.My_Must_net._05_new.MyStruct:.ctor(string) L_0017: nop L_0018: ret 從而可以得出以下結(jié)論: new一個(gè)class時(shí),new完成了以下兩個(gè)方面的內(nèi)容:一是調(diào)用newobj命令來為實(shí)例在托管堆中分配內(nèi)存;二是調(diào)用構(gòu)造函數(shù)來實(shí)現(xiàn)對(duì)象初始化。 new一個(gè)struct時(shí),new運(yùn)算符用于調(diào)用其帶構(gòu)造函數(shù),完成實(shí)例的初始化。 new一個(gè)int時(shí),new運(yùn)算符用于初始化其值為0。 另外必須清楚,值類型和引用類型在分配內(nèi)存時(shí)是不同的,值類型分配于線程的堆棧(stack)上,并變量本身就保存其實(shí)值,因此也不受GC的控制,;而引用類型變量,包含了指向托管堆的引用,內(nèi)存分配于托管堆(managed heap)上,內(nèi)存收集由GC完成。 另外還有以下規(guī)則要多加注意: new運(yùn)算符不可重載。 new分配內(nèi)存失敗,將引發(fā)OutOfMemoryException異常。 對(duì)于基本類型來說,使用new操作符來進(jìn)行初始化的好處是,某些構(gòu)造函數(shù)可以完成更優(yōu)越的初始化操作,而避免了不高明的選擇,例如:string str = new string(*, 100);string str = new string(new char a, b, c);而不是string str = *; 4. 結(jié)論 我能說的就這么多了,至于透了沒透,作者的能量也就這么多了。希望園子的大牛們常來扔塊磚頭,對(duì)我也是一種莫大的促進(jìn)。但是作為基本的原理和應(yīng)用,我想對(duì)大部分的需求是滿足了。希望這種力求深入淺出的介紹,能給你分享new關(guān)鍵字和其本質(zhì)的來龍去脈能有所幫助。接口的無(wú)敵解釋2007年06月13日 星期三 21:32接口簡(jiǎn)單的說接口就是一個(gè)契約或者規(guī)范.比如遙控器,國(guó)家出臺(tái)了一個(gè)國(guó)家遙控器規(guī)范,明文要求所有的遙控器廠家都要遵循這個(gè)規(guī)范,如果不遵循規(guī)范就不給3C認(rèn)證標(biāo)志,就不允許上市出賣.為什么要這個(gè)規(guī)范呢?大家在時(shí)間生活中會(huì)經(jīng)常碰到,甲廠的遙控器不能遙控乙廠的電視,電視遙控器不能遙控其它電器如空調(diào),冰箱.!原因是什么呢?是各個(gè)遙控器都沒有遵循一個(gè)規(guī)范,電波有長(zhǎng)有短,電壓有高有低,導(dǎo)致各自為政,4分5列! 可以想像出國(guó)家遙控器標(biāo)準(zhǔn)只是是規(guī)定遙控器的一些重要技術(shù)指標(biāo),比如要發(fā)射波應(yīng)該多長(zhǎng),電壓應(yīng)該多高,.,但它絕對(duì)不會(huì)規(guī)范出遙控器的材質(zhì),形狀,重量和顏色,也是說規(guī)范把所有同遙控?zé)o關(guān)的東西都拋棄了!每個(gè)遙控器廠家只要遵循了規(guī)范,那么對(duì)遙控器可以有任意的詮釋.比如A廠可以用鐵做,牢固無(wú)比,B廠可以用紙,可以任意折疊,anyway,不管用什么做,做出什么樣子,只要遵循規(guī)范的遙控器就可以遙控所有的電器(當(dāng)然電器廠家也要遵循一定的規(guī)范),甚至可以遙控導(dǎo)彈發(fā)射!利害吧,這就是接口的威力. 再詳細(xì)點(diǎn),接口就是一個(gè)規(guī)范,他和具體的實(shí)現(xiàn)無(wú)關(guān)!接口是規(guī)范(虛的),他只是一張紙,也是說在實(shí)際的使用中接口只有依托一個(gè)實(shí)現(xiàn)了它的類的實(shí)例,才會(huì)有意義,如上面的各個(gè)廠家做的遙控器產(chǎn)品.每個(gè)實(shí)現(xiàn)接口的類(廠家)必需實(shí)現(xiàn)接口中所有的功能. 一旦一個(gè)類實(shí)現(xiàn)了一個(gè)接口,就可說一個(gè)類和接口捆綁了(這個(gè)很重要,做題目的時(shí)候會(huì)用到) 來個(gè)例子 interface 遙控器規(guī)范 /國(guó)家定義的遙控器規(guī)范 ,每個(gè)遙控器廠家必需實(shí)現(xiàn)(詮釋)它 int 波長(zhǎng)(); int 電壓(); class 甲廠鐵遙控器 : 遙控器規(guī)范 /甲廠的遙控器實(shí)現(xiàn)(詮釋)了這個(gè)規(guī)范,它和遙控器規(guī)范捆綁了!好,它可以在市場(chǎng)上出售了 public int 波長(zhǎng)(); /規(guī)范上定義的指標(biāo) public int 電壓(); /規(guī)范上定義的指標(biāo) public int 形狀() 正方形; /甲廠自己對(duì)該產(chǎn)品的詮釋 public int 材質(zhì)() ( 鐵 ; /甲廠自己對(duì)該產(chǎn)品的詮釋 class 乙廠紙遙控器 : 遙控器規(guī)范 /甲廠的遙控器實(shí)現(xiàn)(詮釋)了這個(gè)規(guī)范,它和遙控器規(guī)范捆綁了!好,它可以在市場(chǎng)上出售了 public int 波長(zhǎng)(); /規(guī)范上定義的指標(biāo) public int 電壓(); /規(guī)范上定義的指標(biāo) public int 形狀()( 圓形); /甲廠自己對(duì)該產(chǎn)品的詮釋,是圓形 public int 材質(zhì)()( 紙); /甲廠自己對(duì)該產(chǎn)品的詮釋,用紙做,好酷! class 電器 procedure 接收遙控(遙控器規(guī)范 ) /電器上,接收遙控指令 . 接收(遙控器規(guī)范.波長(zhǎng)) ; 接收(遙控器規(guī)范.電壓); . static main() 甲廠鐵遙控器 ControlA ; /申明控制器對(duì)象 乙廠紙遙控器 ControlB ; ControlA = new 甲廠鐵遙控器(); /實(shí)例化控制器對(duì)象,這個(gè)時(shí)候系統(tǒng)在托管堆中為該對(duì)象分配了空間 ControlB = new 乙廠紙遙控器() ; 遙控器規(guī)范 ControlInterfaceA = (遙控器規(guī)范)遙控器1 ; /把對(duì)象實(shí)例轉(zhuǎn)換成一個(gè)規(guī)范,為什么呢?因?yàn)槲壹业碾娖?只能識(shí)別遙控器規(guī)范,它識(shí)別不到具體的遙控器 遙控器規(guī)范 ControlInterfaceB = (遙控器規(guī)范)遙控器2; /同上 電器 我家的電器 = new 電器(); 我家的電器.接收遙控(ControlInterfaceA) /我用甲廠遙控器遙控我家的電器. 注意: 這里的ControlInterfaceA是不能單獨(dú)存在的,它必要依賴實(shí)現(xiàn)了遙控器規(guī)范的類的實(shí)例ControlA.道理很簡(jiǎn)單,接口是一個(gè)指針,不會(huì)被分配空間,你就無(wú)法使用,只有和一個(gè)具體類的實(shí)例聯(lián)系了,才有了可以活躍空間. 我家的電器.接收遙控(ControlInterfaceB) /我用乙廠遙控器遙控我家的電器 . /下面是我的的想像,我可以用遙控器來控制導(dǎo)彈發(fā)射! 我的導(dǎo)彈.接收遙控(ControlInterfaceA); 我的導(dǎo)彈.接收遙控(ControlInterfaceB); . -接口的執(zhí)行好了,有了接口的概念,再來談c#程序在運(yùn)行中是如何使用接口的,如何訪問接口函數(shù).具體流程如下 a.當(dāng)調(diào)用一個(gè)接口的函數(shù)時(shí),系統(tǒng)會(huì)去檢查這個(gè)接口對(duì)應(yīng)實(shí)例是什么? b.找到這個(gè)實(shí)例后,再去找這個(gè)實(shí)例對(duì)應(yīng)的實(shí)例類是什么(什么是實(shí)例類,參看讀書筆記二) c.根據(jù)這個(gè)實(shí)例類去檢查該實(shí)例類是否和接口發(fā)生了捆綁(看是否實(shí)現(xiàn)了該接口,冒號(hào)后面就是) d.好!如果實(shí)例類實(shí)現(xiàn)了該接口(發(fā)生了捆綁) ,它就在這個(gè)實(shí)例類中找函數(shù)的定義.然后執(zhí)行該函數(shù).執(zhí)行結(jié)束. e.如果沒找到,他就繼續(xù)往父類找,直到找到第一個(gè)和接口捆綁的父類為止 f.找到后,它再檢查該函數(shù)是否是虛擬函數(shù), g.如果不是,他馬上就執(zhí)行它 . h 如果是,麻煩了,系統(tǒng)又要從頭來過,去檢查該實(shí)例類的函數(shù)是否重載了該函數(shù),.具體過程見(c#讀書筆記2). 例子: Interface I void Func() ; Class A : I public virtual void Func() Console.WriteLine(FuncA); class B : A , I /注意這里的意思? public void Func() Console.WriteLine(FuncB); class C : A public override void Func() Console.WriteLine(FuncC); static main() I a = new A() ; /申明了接口a,并馬上和一個(gè)類的實(shí)例發(fā)生關(guān)系了 I b = new B() ; /申明了接口b,并馬上和一個(gè)類的實(shí)例發(fā)生關(guān)系了 I c = new C() ; /申明了接口c,并馬上和一個(gè)類的實(shí)例發(fā)生關(guān)系了 a.Func() ; /檢查a的實(shí)例A, 發(fā)現(xiàn)A和接口I捆綁了,所以執(zhí)行A的函數(shù)Func ,結(jié)果: FuncA b.Func() ; /檢查b的實(shí)例B, 發(fā)現(xiàn)B和接口I捆綁了,所以執(zhí)行B的函數(shù)Func ,結(jié)果: FuncB c.Func() ; /家常c的實(shí)例C,發(fā)現(xiàn)其沒有和接口I捆綁,系統(tǒng)繼續(xù)找它的父類. 發(fā)現(xiàn)A和I捆綁了,他就去找函數(shù)A,發(fā)現(xiàn)A是虛擬函數(shù),系統(tǒng)又從頭來找類的實(shí)例C,發(fā)現(xiàn)C重載(override)了Func,好了,馬上執(zhí)行該函數(shù). 結(jié)果是FuncC; c#學(xué)習(xí)體會(huì):使用 ref 和 out 傳遞數(shù)組2007年07月10日 星期二 22:49c#學(xué)習(xí)體會(huì):使用 ref 和 out 傳遞數(shù)組(downmoon),希望與大家分享1、與所有的 out 參數(shù)一樣,在使用數(shù)組類型的 out 參數(shù)前必須先為其賦值,即必須由接受方為其賦值。例如:public static void MyMethod(out int arr). arr = new int10; / 數(shù)組arr的明確委派2、與所有的 ref 參數(shù)一樣,數(shù)組類型的 ref 參數(shù)必須由調(diào)用方明確賦值。因此不需要由接受方明確賦值??梢詫?shù)組類型的 ref 參數(shù)更改為調(diào)用的結(jié)果。例如,可以為數(shù)組賦以 null 值,或?qū)⑵涑跏蓟癁榱硪粋€(gè)數(shù)組。例如:public static void MyMethod(ref int arr). arr = new int10; / arr初始化為一個(gè)新的數(shù)組下面的兩個(gè)示例說明 out 和 ref 在將數(shù)組傳遞給方法上的用法差異。示例 1在此例中,在調(diào)用方(Main 方法)中聲明數(shù)組 myArray,并在 FillArray 方法中初始化此數(shù)組。然后將數(shù)組元素返回調(diào)用方并顯示。using System;class TestOut. static public void FillArray(out int myArray) . / 初始化數(shù)組(必須): myArray = new int5 .1, 2, 3, 4, 5; static public void Main() . int myArray; / 初始化數(shù)組(不是必須的!) / 傳遞數(shù)組給(使用out方式的)調(diào)用方: FillArray(out myArray); / 顯示數(shù)組元素 Console.WriteLine(數(shù)組元素是:); for (int i=0; i myArr
溫馨提示
- 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 采購(gòu)合同范本實(shí)務(wù)操作手冊(cè)3篇
- 采購(gòu)合同制定合作雙方權(quán)益的保障3篇
- 采購(gòu)合同評(píng)審表問答3篇
- 采購(gòu)合同的市場(chǎng)趨勢(shì)預(yù)測(cè)3篇
- 采購(gòu)合同中英文版填寫范本3篇
- 采購(gòu)合同框架協(xié)議的簽訂發(fā)展趨勢(shì)3篇
- 采購(gòu)合同提升企業(yè)合同簽訂效率3篇
- 采購(gòu)戰(zhàn)略合同的綠色發(fā)展戰(zhàn)略優(yōu)化3篇
- 2024年度養(yǎng)老機(jī)構(gòu)與志愿者組織合作協(xié)議范本3篇
- 2024年汽車行業(yè)人才招聘與培訓(xùn)合同集錦3篇
- 北疆文化全媒體傳播體系的構(gòu)建與實(shí)踐
- 低血糖暈厥應(yīng)急演練預(yù)案
- 四川省成都市某中學(xué)2024-2025學(xué)年高一年級(jí)上冊(cè)11月期中考試 英語(yǔ)試卷(含答案)
- 2025屆福建省廈門市重點(diǎn)中學(xué)高三第二次聯(lián)考語(yǔ)文試卷含解析
- OpenCV計(jì)算機(jī)視覺基礎(chǔ)教程(Python版)教學(xué)教案
- 2024年度二人合伙光伏發(fā)電項(xiàng)目投資合同3篇
- 2024-2030年中國(guó)室內(nèi)滑雪場(chǎng)市場(chǎng)需求預(yù)測(cè)及發(fā)展規(guī)劃研究報(bào)告
- 期末綜合素養(yǎng)評(píng)價(jià)一(試題)-2024-2025學(xué)年三年級(jí)上冊(cè)科學(xué)教科版
- 期末 (試題) -2024-2025學(xué)年人教PEP版英語(yǔ)六年級(jí)上冊(cè)
- 動(dòng)車運(yùn)用所施工組織設(shè)計(jì)
- 新聞媒體編輯與發(fā)布規(guī)范流程
評(píng)論
0/150
提交評(píng)論