



版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
在類的構(gòu)造函數(shù)中出現(xiàn)表示對正在構(gòu)造的對象本身的引用,在類的方法中出現(xiàn)表示對調(diào)用該方法的對象的引用,在結(jié)構(gòu)的構(gòu)造上函數(shù)中出現(xiàn)表示對正在構(gòu)造的結(jié)構(gòu)的引用,在結(jié)構(gòu)的方法中出現(xiàn)表示對調(diào)用該方法的結(jié)果的引用在C#系統(tǒng)中,this實際上是ー個常量,所以不能使用this++這樣的運(yùn)算this保留字一般用于限定同名的隱蔵成員、將對象本身做為參數(shù)、聲明索引訪問器、判斷傳入?yún)?shù)的對象是否為本身?類和結(jié)構(gòu)的區(qū)別?答:類:類是引用類型在堆上分配,類的實例進(jìn)行賦值只是復(fù)制了引用,都指向同一段實際對象分配的內(nèi)存;類有構(gòu)造和析構(gòu)函數(shù);類可以繼承和被繼承。結(jié)構(gòu):結(jié)構(gòu)是值類型在棧上領(lǐng)(雖然棧的訪問速度比較堆要快,但棧的資源有限放),結(jié)構(gòu)的賦值將分配產(chǎn)生一個新的對象。結(jié)構(gòu)沒有構(gòu)造函數(shù),但可以添加。結(jié)構(gòu)沒有析構(gòu)函數(shù)。結(jié)構(gòu)不可以繼承自另一個結(jié)構(gòu)或被繼承,但和類ー樣可以繼承自接口。.抽象類和接口的區(qū)別?答:抽象類(abstractclass)可以包含功能定義和實現(xiàn),接口(interface)只能包含功能定義抽象類是從ー系列相關(guān)對象中抽象出來的概念,因此反映的是事物的內(nèi)部共性;接口是為了滿足外部調(diào)用而定義的ー個功能約定,因此反映的是事物的外部特性分析對象,提煉內(nèi)部共性形成抽象類,用以表示對象本質(zhì),即“是什么”為外部提供調(diào)用或功能需要擴(kuò)充時優(yōu)先使用接口。接ロ一般只有方法,而沒有數(shù)據(jù)成員或?qū)傩浴3橄箢愑蟹椒?也有數(shù)據(jù)成員或?qū)傩?一般情況下,優(yōu)先考慮用接口,只有當(dāng)可能要訪問到數(shù)據(jù)成員或?qū)傩詴r,用抽象類。.概述深度復(fù)制和淺度復(fù)制深度復(fù)制就是將引用成員指向的對象也進(jìn)行復(fù)制。實際的過程是創(chuàng)建新的引用成員指向的對象,然后復(fù)制對象包含的數(shù)據(jù)。淺度復(fù)制的時候,對于值類型成員,會復(fù)制其本身(值類型變量本身包含了所有數(shù)據(jù),復(fù)制時進(jìn)行按位拷貝);對于引用類型成員(注意它會引用另ー個對象),僅僅復(fù)制引用,而不創(chuàng)建其引用的對象。結(jié)果就是:新對象的引用成員和復(fù)制對象的引用成員指向了同一個對象第十章定義類成員本章內(nèi)容.定義類成員.類成員的其他議題.接ロ的實現(xiàn).部分類知識點.定義字段字段(一般首字母小寫,或下戈I踐開頭):在類中直接定義的變量。變量一定要先聲明,再賦值,才能使用.>命名規(guī)則:1)必須以“字母”ー或@符號開頭.ー不要以數(shù)字開頭2)后面可以跟任意“字母”、數(shù)字、下劃線.定義變量時,變量名要有意義A注意:1)你起的變量名不要與c#系統(tǒng)中的關(guān)鍵字重復(fù).2)在c#中,大小寫是敏感的>字段用標(biāo)準(zhǔn)的變量聲明格式和前面介紹的修飾符來聲明(也可以初始化),例如:classmyClass(publicintMylnt;)公共字段推薦用PascalCasing的形式來命名,私有字段沒有推薦的命名形式,一般使用cameICasing的形式來命名。字段可以使用關(guān)鍵字readonly,表示這個字段只能在執(zhí)行構(gòu)造函數(shù)的過程中賦值,或由初始化語句賦值,例如:classmyClasspublicreadonlyintMylnt=17;)字段也可以使用static聲明為靜態(tài)的:classmyClass(publicstaticintMylnt;).定義屬性屬性(一般首字母大寫):定義一個public變量,這個變量里含有g(shù)et,set兩個方法(屬性不是變量,其實質(zhì)是函數(shù))0get讀取屬性,return返回讀取值,set寫屬性,關(guān)鍵字value存儲用戶賦的值。字段與屬性的區(qū)別就是可以進(jìn)行非法值的判斷。允許外部訪問的變量一定要聲明為屬性。它是代表類的實例或類中的ー個數(shù)據(jù)項的成員。像字段:它是命名的類成員、有類型、可以被賦值和讀取;不像字段:它是函數(shù)成員、不為數(shù)據(jù)存儲分配內(nèi)存、它執(zhí)行代碼。屬性可以使用vartual、override和abstract關(guān)鍵字,但是不能將這幾個關(guān)鍵字用于字段。>語法:[訪問修飾符]類型名屬性名{get{return字段;set(私有字段=valueJ))功能:允許外部訪問的變量必須設(shè)為屬性,可以防止用戶設(shè)非法值,用來保護(hù)私有字段賦值的正確性。get塊一般有一個屬性類型的返回值,簡單的屬性一般與一個私有字段相關(guān)聯(lián),用來控制對這個字段的訪問,這是get塊可以直接返回該字段的值;上面的字段外部不能訪問,只能通過屬性來訪問該字段。set函數(shù)以類似的方式把ー個值賦給字段,這里可以使用關(guān)鍵字value引用用戶提供的屬性值;value值等于類型和屬性相同的一個值,如果屬性的類型和字段的類型相同,就不用進(jìn)行類型轉(zhuǎn)換。>靜態(tài)屬性:不能訪問類的實例成員,雖然它們能被實例成員訪問;它總是存在,不管類是否有實例;當(dāng)從類的外部訪問時,必須使用類名引用,而不是實例名;>其設(shè)計目的主要是為了實現(xiàn)面向?qū)ο螅ī柀枺┲械姆庋b思想。根據(jù)該思想,字段最好設(shè)為private,一個精巧的類最好不要直接把字段設(shè)為公有提供給客戶調(diào)用端直接訪問。.定義方法方法使用標(biāo)準(zhǔn)的函數(shù)格式,以及可訪問性,和可選的static修飾符來聲明,例如:classmyClasspublicstringMyStringOreturn"這是一個方法”;)}解析:classmyClass(〃開始聲明方法代碼publicstringMyStringO(return"這是一個方法”;)〃結(jié)束聲明方法代碼)公共方法也用PascalCasing的形式來命名。>注意:如果聲明了static關(guān)鍵字,這個方法就只能通過類來訪問,而不能通過對象實例還訪問。>也可以在方法定義中使用下面的關(guān)鍵字:virtual 方法可以重寫;abstract 方法必須在非抽象的派生類中重寫(只用于抽象類)override一一一方法重寫了一個基類方法(要重寫方法,必須用這個關(guān)鍵字)extern 方法定義在其他地方;構(gòu)造方法是ー種創(chuàng)建對象的特殊方法,方法名和類名ー樣,沒有返回值,連void都不用,就是為了初始化類的成員。構(gòu)造方法不能被。verride。構(gòu)造函數(shù)可以有參數(shù),new對象的時候傳遞函數(shù)參數(shù)即可。如果不指定構(gòu)造函數(shù),則類有一個默認(rèn)的無參構(gòu)造函數(shù)。如果指定了構(gòu)造函數(shù),則不再有默認(rèn)的無參構(gòu)造函數(shù),如果需要無參構(gòu)造函數(shù),則需要自己來寫。構(gòu)造函數(shù)可以臓,也就是有多個參數(shù)不同的構(gòu)造函數(shù)。使用構(gòu)造方法的好處:1.對多個屬性進(jìn)行賦值時,不需要重復(fù)的寫實例名。2.可以保證用戶在newー個對象的時候必須對某ー個屬性進(jìn)行賦值。3.在newー個對象時,對只讀屬性進(jìn)行初始化。在方法定義中,被virtual修飾的方法稱為虛函數(shù)。是沒有實現(xiàn)的,可由子類繼承并重寫的函數(shù)。在方法定義中,被修飾的方法稱為虛函數(shù)抽象函數(shù):規(guī)定其非虛子類必須實現(xiàn)的函數(shù),必須被重寫>定義方法一般有以下幾種://有返回值方法//調(diào)用例子://inti=2;//intresult=Add(i);//Console.WriteLine(result);//Console.WriteLine(i);//輸出后結(jié)果為3和2〃參數(shù)為值類型,原值不被修改publicstaticintAdd(intToNumber)(intsum=0;for(inti=1;i<=ToNumber;i++)(sum+=i;Ireturnsum;}〃無返回值方法〃調(diào)用例子://AddVoid(2);//輸出后結(jié)果為3publicstaticvoidAddVoid(intToNumber)(intsum=0;for(inti=1;i<=ToNumber;i++)(sum+=i;)Console.WriteLine(sum);I〃引用類型方法〃調(diào)用例子//Testobj=newTest()://AddObject(obj);//Console.WriteLine(obj.Number);〃輸出結(jié)果為3〃傳入obj對象的的Number屬性,原屬性值是1,傳入后,對象的屬性也被修改〃引用類型參數(shù)是傳地址,不是傳值,所有引用類型的原值也會被修改publicstaticvoidAddObject(Testobj){obj.Number+=2;}〃數(shù)組參數(shù)方法//調(diào)用例子//int[]Number={1,2};//intresult=AddArray(Number);//Console.WriteLine(result);〃輸出結(jié)果為3publicstaticintAddArray(int[]ToNumber){intnum=0;foreach(variinToNumber){num+=i;}returnnum;)〃數(shù)組參數(shù)簡化簡化調(diào)用//調(diào)用例子//intResult=AddArrayV2(l,2,3);//Console.WriteLine(Result);〃輸出結(jié)果為6〃這種寫法簡化數(shù)組參數(shù),調(diào)用時不需要定義數(shù)組,會自動將參數(shù)轉(zhuǎn)換為數(shù)組值處理publicstaticintAddArrayV2(paramsint[]ToNumber){intnum=0;foreach(variinToNumber){num+=i;}returnnum;)〃傳地址參數(shù),參數(shù)必須初始值//調(diào)用例子//intNumber=2;//AddRef(refNumber);//Console.WriteLine(Number);//輸出結(jié)果為4〃普通的寫法值類型是直接傳值,引用類型傳地址〃雖然Number是值類型,但是用ref就變成傳地址了,所以原值也會被修改〃注意的是,調(diào)用的時候也要加ref,而且參數(shù)傳入前必須有初始值publicstaticvoidAddRef(refintToNumber)ToNumber+=2;〃傳地址參數(shù),參數(shù)無初始值//調(diào)用方法//intNumber;//AddOut(outNumber);//Console.WriteLine(Number);〃輸出結(jié)果為3〃此方法和ref一樣,也是將值類型參數(shù)傳入地址,原值也會被修改〃與ref不同的是,參數(shù)有方法體提供初始值publicstaticvoidAddOut(outintToNumber){ToNumber=1;ToNumber+=2;}?靜態(tài)方法和實例方法(定義和調(diào)用)靜態(tài)實例(非靜態(tài))static關(guān)鍵字不需要static關(guān)鍵字使用類名調(diào)用使用實例對象調(diào)用在靜態(tài)方法中,可以訪問靜態(tài)成員在實例方法中:可以直接訪問靜態(tài)成員在靜態(tài)方法中,不可以直接訪問實例成員在實例方法中:可以直接訪問實例成員調(diào)用前初始化(*)實例化對象時初始化(*).部分類也可以定義部分方法。部分方法在部分類中定義,但沒有方法體,在另ー個部分類中執(zhí)行。在這兩個部分類中,都要使用partial關(guān)鍵字。publicpartialclassMyClass(partialvoidMyPartialMethodO;)publicpartialclassMyClass(partialvoidMyPartialMethod()(//Methodimplementation)}部分方法也可以是靜態(tài)的,但它們總是私有的,且不能有返回值。它們使用的任何參數(shù)都不能是out參數(shù),但可以是ref參數(shù)。部分方法還不能使用virtual、abstract、override、new、sealed和extern修飾符。有了這些限制,就不太容易看出部分方法的作用了。實際上,部分方法在編譯代碼時非常重要,其用法倒并不重要。考慮下面的代碼:publicpartialclassMyClass(partialvoidDoSomethingElse();publicvoidDoSomethingOConsole.WriteLine(uDoSomething()executionstarted.);DoSomethingElse();Console.WriteLine("DoSomething()executionfinished.n);i)publicpartialclassMyClass(partialvoidDoSomethingElse()(Console.WriteLine("DoSomethingElse()called.n);I:這段代碼定義了部分方法DoSomethingElse,在第一個部分類中定義,在第二個部分類中執(zhí)行〇在控制臺應(yīng)用程序中調(diào)用DoSomething時,輸出如下所示:DoSomething()executionstarted.DoSomethingElse()called.DoSomething()executionfinished.如果刪除第二個部分類定義,或者刪除部分方法的全部執(zhí)行代碼(注釋掉代碼),輸出就如下所示:DoSomething()executionstarted.讀者可能認(rèn)為,調(diào)用DoSomethingElse時,運(yùn)行庫發(fā)現(xiàn)該方法沒有執(zhí)行代碼,因此會繼續(xù)執(zhí)行下一行代碼。但實際上,編譯代碼時,如果代碼包含ー個沒有執(zhí)行代碼的部分方法,編譯器會完全刪除該方法,還會刪除對該方法的所有調(diào)用。執(zhí)行代碼時,不會檢查執(zhí)行代碼,因為沒有檢查方法的調(diào)用。這會略微提高性能。與部分類ー樣,在定制自動生成的代碼或設(shè)計器創(chuàng)建的代碼時,部分方法是很有用的。設(shè)計器會聲明部分方法,用戶根據(jù)具體情形選擇是否執(zhí)行它。如果不執(zhí)行它,就不會影響性能,因為該方法在編譯過的代碼中不存在。.訪問權(quán)限訪問修飾符:public:可以在任何地方被訪問internal:只能在本項目中被訪問(在類這個級別,不寫訪問修飾符時默認(rèn)的)private:只能在本類中被訪問(在類中跟方法中不寫訪問修飾符時所默認(rèn)的)preotectd:只能在本類和子類中被訪問protectedinternal:修飾的屬性/方法只能在它的在同一個程序集中的子類被訪問不在同一個命名空間下的類,不能直接訪問,有2種方法可以訪問:1.通過using引用的命名空間。2.寫全稱.命名空間.類名在靜態(tài)方法中,只能訪問靜態(tài)屬性,不能直接訪問實例屬性。在static成員中不能直接調(diào)用非static成員,在非static成員中可以調(diào)用static成員。私有成員也會被繼承,但是不能被訪問。一般用private修飾后讓他們看上去似乎是不能被繼承的,但實際上確實被繼承了。6.接口(interface)只含有共有抽象方法(publicabstractmethod)的類〇這些方法必須在子類中被實現(xiàn)。定義接口的一般形式為:[attributes][modifiers]interfaceidentifier[:base-list]{interface-body}[;]說明:1、attributes(可選):附加的定義性信息。2、modifiers(可選):允許使用的修飾符有new和四個訪問修飾符。分別是:new、public、protected、internal、privateo在ー個接口定義中同一修飾符不允許出現(xiàn)多次,new修飾符只能出現(xiàn)在嵌套接口中,表示覆蓋了繼承而來的同名成員。Thepublic,protected,internal,andprivate修飾符定義了對接ロ的訪問權(quán)限。3、identifier:接口名稱。4、base-list(可選):包含一個或多個顯式基接口的列表,接口間由逗號分隔。5、interface-body:接口主體,ー個接口的接口主體定義接口的成員。6、接ロ可以是命名空間或類的成員,并且可以包含下列成員的簽名:方法、屬性、索引器.7、ー個接口可從ー個或多個基接口繼承。如:interfaceIMyExample{stringthis[intindex]{get;set;}eventEventHandlerEvenvoidFind(intvalue);stringPoint{get;set;}ipublicdelegatevoidEventHandler(objectsender,Evente);上面例子中的接口包含ー個索引this、一個事件Even、ー個方法Find和一個屬性Point。C#中接口和類的異同:接口和類都是類,不同的是,接口只包含方法或?qū)傩缘穆暶?不包含具體實現(xiàn)方法的代碼,接口可以實現(xiàn)多繼承,而類只能是單繼承,繼承接口的類必須實現(xiàn)接口中聲明的方法或?qū)傩浴=涌谑且粋€純粹的抽象類,沒有任何實際的東西,只是定義了一個框架,而抽象類里面可以有實際的ー個方法,并不要求所有的方法都是抽象的。可以實現(xiàn)ー個接口中的所有方法,也可以繼承一個抽象的類,然后覆寫其中的方法。接ロー般只有方法,而沒有數(shù)據(jù)成員或?qū)傩浴3橄箢愑蟹椒?也有數(shù)據(jù)成員或?qū)傩?一般情況下,優(yōu)先考慮用接口,只有當(dāng)可能要訪問到數(shù)據(jù)成員或?qū)傩詴r,用抽象類。接口是抽像類的變體。在接口中,所有方法都是抽像的。多繼承性可通過實現(xiàn)這樣的接口而獲得。接口中的所有方法都是抽像的,沒有一個有程序體。接口只可以定義staticfinal成員變量。接口可以繼承接口。接口的成員不能使用internal修飾符。接口可以包含屬性、方法、索引指示器和事件,但不能包含常量、域、操作符、構(gòu)造函數(shù)和析構(gòu)函數(shù),而且也不能包含任何靜態(tài)成員。接口好比ー種模版,這種模版定義了對象必須實現(xiàn)的方法,其目的就是讓這些方法可以作為接口實例被引用。接口不能被實例化。類可以實現(xiàn)多個接ロ并且通過這些實現(xiàn)的接口被索引。接口變量只能索引實現(xiàn)該接口的類的實例。C#中的接口與類不同,可以使用多繼承,即ー個子接口可以有多個父接口。但如果兩個父成員具有同名的成員,就產(chǎn)生了二義性(這也正是C#中類取消了多繼承的原因之一),這時在實現(xiàn)時最好使用顯式的聲明示例:usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceExamplel7(classProgram]〃ー個完整的接口聲明示例interfacelExample{〃屬性stringP{get;set;〃方法stringF(intValue);〃事件eventEventHandlerE;〃索引指示器stringthis[intIndex]{get;set;)interfaceIA{'intCount{get;set;}]interfaceIB{intCount();i〃IC接口從IA和IB多重繼承interfaceIC:IA,IBclassC:ICprivateintcount=100;〃顯式聲明實現(xiàn)IA接口中的Count屬性intIA.Count{get{return100;}set{count=value;})〃顯式聲明實現(xiàn)IB接口中的Count方法intIB.Count(){returncount*count;}IstaticvoidMain(stringロargs){CtmpObj=newC();〃調(diào)用時也要顯式轉(zhuǎn)換Console.WriteLine〈Countproperty-{〇},
((IA)tmpObj).Count);Console.WriteLine(Countfunction-{0},((IB)tmpObj).Count());Console.ReadLineO;結(jié)果:Countproperty:100Countfunction:100007.認(rèn)識類圖PersonClass金字段」屬性ヨ金字段」屬性ヨ▼PersonOTeacherClassTeacherClassPersonと字段マ屬性サSalary:int才YearsOfServlce:intコ方法SayHi0:voidTeacher0StudentClassPerson五字段屬性ザHobby:string"TPopularity:int,方法MSayHl0:voidVStudent()通用類圖類名Student■age;int
?name;string
+Name:string+SayHi():yoid8.New關(guān)鍵字可以在派生類中隱蔵基類的方法,也就說在使用派生類的方法是調(diào)用的方法是C#New關(guān)鍵字新定義出來的方法,而不是基類的方法。在不使用C#New關(guān)鍵字來隱蔵基類方法也是可以的,編譯器會出現(xiàn)ー個警告,提示如果有意去隱藏基類的方法,請使用C#New關(guān)鍵字修飾。學(xué)習(xí)難點String可以看做是char的只讀數(shù)組,String的字符串的重要特性,不可變型,即字符串一旦聲明就不可改變。所以只能通過索引來讀取指定位置的char,不能對指定位置char進(jìn)行修改。要想修改可以用以下方式實現(xiàn):Strings="heklo”;char[]arr=s.ToCharArray();arr[2]="1";String是密封類,所以不能被繼承。String有l(wèi)ength。這個方法。數(shù)組沒有l(wèi)ength()這個方法,但有l(wèi)ength的屬性。當(dāng)我們實例化一個類時,系統(tǒng)會自動對這個類的屬性進(jìn)行初始化,數(shù)字類型初始為〇/〇?〇,string類型初始為null,char類型初始為:¥0。int,datetime,bool,char等類型都屬于值類型(ValueType),賦值的時候是傳遞拷貝。普通的對象則是引用類型,賦值的時候是傳遞引用。如:inti=10;intj;i++;Console.WriteLine(j);輸出10Personpl=newPerson(lO);Personp2=pl;pl.Age++;Console.WriteLine(p2.Age);輸出11const和readonly有什么區(qū)別?答:const可以用于類的成員常量和局部常量,必須在聲明時賦值,之后不可以對常量進(jìn)行賦值。而readonly只能用于類的成員變量不能用于局部變量,在聲明時可以不賦值,除了在構(gòu)造函數(shù)中可以再次賦值外,其它的地方和constー樣也不能賦值。接口和抽象類有什么區(qū)別?你選擇使用接口和抽象類的依據(jù)是什么?答:(1)抽象類可以有抽象成員(無具體實現(xiàn)),也可以有非抽象成員(有具體實現(xiàn));接口只有抽象成員。(2)一個類不能同時繼承多個抽象類,ー個類可以同時實現(xiàn)多個接口。如果多個子類中有很多代碼是重復(fù)的,這時采用抽象類,因為可以將這些代碼放到抽象類的非抽象方法中,這樣可以達(dá)到代碼復(fù)用。當(dāng)實現(xiàn)多個接口時因為抽象類不支持,只能使用接口。.成員變量和成員函數(shù)前加static的作用?答:它們被稱為常成員變量和常成員函數(shù),又稱為類成員變量和類成員函數(shù)。分別用來反映類的狀態(tài)。比如類成員變量可以用來統(tǒng)計類實例的數(shù)量,類成員函數(shù)負(fù)責(zé)這種統(tǒng)計的動作。.為什么不能指定接口中方法的修飾符?接口中的方法用來定義對象之間通信的契約,指定接口中的方法為私有或保護(hù)沒有意義。他們默認(rèn)為公有方法。常見企業(yè)面試題1.classPerson1(intage;publicintAgeset{}get{return18;}IIstaticvoidMain(string[]args){Personlpl=newPerson1();pl.Age=30;pl.Age=pl.Age+1;Console.WriteLine(pl.Age);}(輸出I8)classPerson2intage;publicintAge(set(this.Age=value;]get{returnthis.Age;]}staticvoidMain(string[]args){Person2p2=newPerson2();p2.Age=30;Console.WriteLine(p2.Age);I(死循環(huán),自己給自己賦值,應(yīng)p2.age=30)2.以下程序有什么錯?publicclassTestClassprivateintcount;privatestaticinty;publicstaticvoidsetvalue()(count=l;y=i;})答:在靜態(tài)函數(shù)中只能訪問靜態(tài)成員變量;以上代碼訪問了實例成員。.傳值和傳引用,傳引用又兩種方式,ref和out,ref要求變量在傳參前賦值,out可以不賦值。傳引用必須是ー個地址,傳值是指將棧中的值拷貝到函數(shù)的參數(shù),傳引用表示傳入的變量和接收參數(shù)是同一個變量publicclassTest{publicintmyVar;publicintMyProperty(get{returnmyVar;}set{myVar=value;})}以上這個類中有字段和屬性i=100;有一個方法傳遞引用,調(diào)用方式如下Testt=newTest();F(reft.MyProperty);以上代碼編譯不能通過,因為屬性不是變量,其實質(zhì)是函數(shù),如下則可通過Testt=newTest();F(reft.myVar);因為字段是變量.能夠?qū)⒎庆o態(tài)的方法覆寫成靜態(tài)方法么?不能,覆寫方法的簽名必須與被覆寫方法的簽名保持一致,除了將virtual改為override。.可以覆寫私有的虛方法么?不可以,甚至子類中無法訪問父類中的私有方法。.能夠?qū)崿F(xiàn)允許某個類被繼承,但不允許其中的某個方法被覆寫么?可以,標(biāo)記這個類為public,并標(biāo)記這個方法為sealed。.Strings=newString("xyz”);創(chuàng)建了幾個StringObject?答:兩個對象,ー個是"xyz",ー個是指向"xyz”的引用對象s。8,在C#中,stringstr=null與stringstr=" "有何區(qū)別?答:stringstr=null是不給他分配內(nèi)存空間,而stringstr="”給它分配長度為空字符串的內(nèi)存空間.publicstaticintCount=0;staticClassi()(Count++;}publicClassi()(Count++;))Classiol=newClassi();Classio2=newClassi();請問,Classi.Count的值是多少?().以下哪些可以作為接口成員?(多選)A.方法B.屬性C.字段D.事件E.索引器F.構(gòu)造函數(shù)G.析構(gòu)函數(shù)(答案ABDE).abstractclassBaseClass(publicvirtualvoidMethodAO(IpublicvirtualvoidMethodBOclassClassi-BaseClass(publicvoidMethodA(stringarg)publicoverridevoidMethodB())classClass2'Classi(newpublicvoidMethodB()(classMainClass(publicstaticvoidMain(string[]args)(Class2〇二newClass2();Console.WriteLine(o.MethodA());)請問,o.MethodA調(diào)用的是:(A)BaseClass.MethodAClass2,MethodAClassi.MethodAD,都不是集合、比較和轉(zhuǎn)換前面討論了C#中所有的基本OOP技術(shù),讀者還應(yīng)熟悉ー些比較高級的技術(shù)。本章的主要內(nèi)容如ド:集合:集合可以維護(hù)對象組。與前面章節(jié)使用的數(shù)組不同,集合可以包含更高級的功能,例如,控制對它們包含的對象的訪問、搜索和排序等。本章將介紹如何使用和創(chuàng)建集合類,學(xué)習(xí)掌握它們的ー些強(qiáng)大技術(shù)。比較:在處理對象時,常常要比較它們。這對于集合尤其重要,因為這是排序的實現(xiàn)方式。本章將介紹如何以各種方式比較對象,包括運(yùn)算符重載,使用IComparable和IComparer接口對集合排序。轉(zhuǎn)換:在前面的章節(jié)中,介紹了如何把對象從ー種類型強(qiáng)制轉(zhuǎn)換為另ー種類型。本章討論如何定制類型轉(zhuǎn)換,以滿足自己的要求。集合第5章介紹了如何使用數(shù)組創(chuàng)建包含許多對象或值的變量類型。但數(shù)組有一定的限制。最大的限制是一旦創(chuàng)建好數(shù)組,它們的大小就是固定的,不能在現(xiàn)有數(shù)組的末尾添加新項,除非創(chuàng)建一個新的數(shù)組。這常常意味著用于處理數(shù)組的語法比較復(fù)雜。OOP技術(shù)可以創(chuàng)建在內(nèi)部進(jìn)行這些處理的類,因此簡化了使用項列表或數(shù)組的代碼。C#中的數(shù)組實現(xiàn)為System.Array類的實例,它們只是集合類中的ー種。集合類一般用于處理對象列表,其功能比簡單數(shù)組要多,這些功能是通過實現(xiàn)System.Collections名稱空間中的接口而獲得的,因此集合的語法已經(jīng)標(biāo)準(zhǔn)化了。這個名稱空間還包含其他ー些有趣的東西,例如,以與System.Array不同的方式實現(xiàn)這些接口的類。集合的功能(包括基本函數(shù),例如,用[index]語法訪問集合中的項)可以通過接口來實現(xiàn),該接口不僅沒有限制我們使用基本集合類,例如System.Array,相反,我們還可以創(chuàng)建自己的定制集合類。這些集合可以專用于要枚舉的對象(即要從中建立集合的對象)。這么做的一個優(yōu)點是定制的集合類可以是強(qiáng)類型化的。也就是說,從集合中提取項時,不需要把它們轉(zhuǎn)換為正確的類型。另ー個優(yōu)點是提供專用的方法,例如,可以提供獲得項子集的快捷方法,在撲克牌示例中,可以添加一個方法,獲得特定suit中的所有Card項。
System.Collections名稱空間中的幾個接口提供了基本的集合功能:lEnumerable可以迭代集合中的項。[Collection(繼承于【Enumerable)可以獲取集合中項的個數(shù),并能把項復(fù)制到ー?個簡單的數(shù)組類型中。IList(繼承于lEnumerable和【Collection)提供了集合的項列表,并可以訪問這些項,以及其他ー些與項列表相關(guān)的功能。【Dictionary(繼承于【Enumerable和【Collection)類似于【List,但提供r可通過鍵碼值而不是索引訪問的項列表。System.Array類實現(xiàn)了【しist、【Collection和【Enumerable,但不支持IList的ー一些更高級的功能,它表示大小固定的項列表。使用集合Systems.Collections名稱空間中的類System.Collections.ArrayList也實現(xiàn)了【List、ICollection和!Enumerable接口,但實現(xiàn)的方式比System.Array更復(fù)雜。數(shù)組的大小是固定的(不能增加或刪除元素),而這個類可以用于表示大小可變的項列表。為了更準(zhǔn)確地理解這個高級集合的功能,下面介紹一個使用這個類和一個簡單數(shù)組的示例。試試看:數(shù)組和高級集合(1)在目錄C:\BegVCSharp\Chapterl1'下倉リ建一個新的控制臺應(yīng)用程序ChllExOlo(2)在SolutionExplorer窗口中右擊項目,選擇AddIClass選項,給項目添加3個新類:Animal>Cow和Chicken。(3)修改Animal.cs中的代碼,如下所示:namespaceChilExOlpublicabstractclassAnimal
protectedstringname;publicstringName(get{returnname;}set(name=value;}}publicAnimal()(name="Theanimalwithnoname";}publicAnimal(stringnewName)(name=newName;}publicvoidFeed()Console.WriteLine("{0}hasbeenfed?”,name);⑷修改Cow.cs中的代碼,如下所示:namespaceChllExOl(publicclassCow:Animal{publicvoidMilk()(Console.WriteLine("{0}hasbeenmilked.",name);)publicCow(stringnewName):base(newName)()}}⑸修改Chicken.cs中的代碼,如下所示:namespaceChllExOl{publicclassChicken:Animal{publicvoidLayEgg()(Console.WriteLine(n{0}haslaidanegg.”,name);publicChicken(stringnewName):base(newName)))(6)修改Program.es中的代碼,如下所示:usingSystem;usingSystem.Collections;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;namespaceChllExOl{classProgram{staticvoidMain(string[]args)(Console.WriteLine("CreateanArraytypecollectionofAnimal"objectsanduseit:");Animal[]animalArray=newAnimal[2];CowmyCowl=newCow("Deirdre");animalArray[0]=myCowl;animalArray[1]=newChicken("Ken");foreach(AnimalmyAnimalinanimalArray)Console.WriteLine(nNew{0}objectaddedtoArraycollection,n+"Name={1}",myAnimal.ToString(),myAnimal.Name);)Console.WriteLine("Arraycollectioncontains{0}objects.",animalArray.Length);animalArray[0].Feed();((Chicken)animalArray[1]).LayEgg();Console.WriteLine();Console.WriteLine("CreateanArrayListtypecollectionofAnimal"+"objectsanduseit:");ArrayListanimalArrayList=newArrayList();CowmyCow2=newCow("Hayley");animalArrayList.Add(myCow2);animalArrayList.Add(newChicken("Roy"));foreach(AnimalmyAnimalinanimalArrayList)(Console.WriteLine("New{0}objectaddedtoArrayListcollection,"+"Name={1}",myAnimal.ToString(),myAnimal.Name);}Console.WriteLine("ArrayListcollectioncontains{0}objects,”,animalArrayList.Count);((Animal)animalArrayList[0]).Feed();((Chicken)animalArrayList[1]).LayEgg();Console.WriteLine();Console.WriteLine("AdditionalmanipulationofArrayList:");animalArrayList.RemoveAt(0);((Animal)animalArrayList[0]).Feed();animalArrayList.AddRange(animalArray);((Chicken)animalArrayList[2]).LayEgg();Console.WriteLine("Theanimalcalled{0}isatindex{1}."zmyCowl.Name,animalArrayList.IndexOf(myCowl));myCowl.Name="Janice";Console.WriteLine("Theanimalisnowcalled{0}.",((Animal)animalArrayList[1]).Name);Console.ReadKey();)}}(7)運(yùn)行該應(yīng)用程序,其結(jié)果如圖!1-I所示SSfile://^::/Users/Kar1i/AppData/Local/TemporaryProjects/Chl1Ex01/bin/Debug/Ch11Ex01.EXECreateanfirraytypecollectionoffinInalobjectsanduseit:NewChllExOl.Cowobjectaddedtofirraycollection,Naroe=DeirdreNewChllEx01.ChickenobjectaddedtoArraycollection.Name=Kenfirraycollectioncontains2objects.Deirdrehasbeenfed.Kenhaslaidanegg.CreateanfirrayListtypecollectionoffinimalobjectsanduseit:NewChllEx01.CowobjectaddedtofirrayListcollection*Nane=HayleyNewChllEx01.ChickenobjectaddedtofirrayListcollection.Name-RoyfirrayListcollectioncontains2objects.Hayleyhasbeenfed.Royhaslaidanegg.fidditionalmanipulationoffirrayList:Royhasbeenfed.Kenhaslaidaneg”TheanimalcalledDeirdreisatindex1.TheanimalisnowcalledJanice.圖11-1示例的說明這個示例創(chuàng)建了兩個對象集合,第一個集合使用System.Array類(這是ー個簡單的數(shù)組),第二個集合使用System.Collections.ArrayList類。這兩個集合都是Animal對象,在Animal.cs中定義。Anima!類是抽象類,所以不能進(jìn)行實例化。但通過多態(tài)性(詳見第8章),可以使集合中的項成為派生于Animal類的Cow和Chicken類實例。這些數(shù)組在Classl.cs的Main。方法中創(chuàng)建好后,就可以顯示其特性和功能。有幾個處理操作可以應(yīng)用到Array和ArrayList集合上,但它們的語法略有區(qū)別。也有ー些操作只能使用更高級的ArrayList類型。下面首先通過比較這兩種集合的代碼和結(jié)果,討論一下這兩種集合的類似操作。首先是集合的創(chuàng)建。對于簡單的數(shù)組來說,必須用固定的大小來初始化數(shù)組,才能使用它。下面使用第5章介紹的標(biāo)準(zhǔn)語法創(chuàng)建數(shù)組animalArray:Animal[]animalArray=newAnimal[2];而ArrayList集合不需要初始化其大小,所以可以使用下面的代碼創(chuàng)建列表animalArrayList:ArrayListanimalArrayList=newArrayList();這個類還有另外兩個構(gòu)造函數(shù)。第一個構(gòu)造函數(shù)把現(xiàn)有的集合作為ー個參數(shù),把現(xiàn)有集合的內(nèi)容復(fù)制到新實例中;而另ー個構(gòu)造函數(shù)通過ー個參數(shù)設(shè)置集合的容量(capacity)。這個容量用ー個int值指定,設(shè)置集合中可以包含的項數(shù)。但這并不是真實的容量,因為如果集合中的項數(shù)超過了這個值,容量就會自動增大一倍。因為數(shù)組是引用類型(例如,Animal和Animal派生的對象),所以用ー個長度初始化數(shù)組并沒有初始化它所包含的項。要使用ー個指定的項,該項還需要初始化,即需要給這個項賦予初始化了的對象:CowmyCowl=newCow("Deirdre");animalArray[0]=myCowl;animalArray[1]=newChicken("Ken");這段代碼以兩種方式完成該初始化任務(wù):用現(xiàn)有的Cow對象來賦值,或者通過創(chuàng)建一個新的Chicken對象來賦值。主要的區(qū)別是前者引用了數(shù)組中的對象一我們在代碼的后面就使用了這種方式。對于ArrayList集合,它沒有現(xiàn)成的項,也沒有null引用的項。這樣就不能以相同的方式給索引賦予新實例。我們使用ArrayList對象的Add()方法添加新項:CowmyCow2=newCow("Hayley");animalArrayList.Add(myCow2);animalArrayList.Add(newChicken("Roy"));除了語法略有不同外,還可以用相同的方式把新對象或現(xiàn)有的對象添加到集合中。以這種方式添加完項后,就可以使用與數(shù)組相同的語法來重寫它們,例如:animalArrayList[0]=newCow("Alma");但不能在這個示例中這么做。第5章介紹了如何使用foreach結(jié)構(gòu)迭代一個數(shù)組。這是可以的,因為System.Array類實現(xiàn)了【Enumerable接口,這個接口的唯一方法GetEnumerator。可以迭代集合中的各項。后面將詳細(xì)討論這一點。在代碼中,我們寫出了數(shù)組中每個Animal對象的信息:foreach(AnimalmyAnimalinanimalArray)Console.WriteLine("New{0}objectaddedtoArraycollection,"Name={1}",myAnimal.ToString(),myAnimal.Name);)這里使用的ArrayList對象也支持IEnumerable接口,并可以與foreach一I起使用,此時語法是相同的:foreach(AnimalmyAnimalinanimalArrayList){Console.WriteLine("New{0}objectaddedtoArrayListcollection,"+"Name={1}",myAnimal.ToString(),myAnimal.Name);}接著,使用數(shù)組的Length屬性,在屏幕上輸出數(shù)組中元素的個數(shù):Console.WriteLine("Arraycollectioncontains{0}objects.",animalArray.Length);也可以使用ArrayList集合得到相同的結(jié)果,但要使用Count屬性,該屬性是【Collection接口的一部分:Console.WriteLine("ArrayListcollectioncontains{0}objects.",animalArrayList.Count);集合一無論是簡單的數(shù)組,還是比較復(fù)雜的集合一都用得不多,除非它們可以訪問屬于它們的項。簡單數(shù)組是強(qiáng)類型化的,可以直接訪問它們所包含的項類型。所以可以直接調(diào)用項的方法:animalArray[0].Feed();數(shù)組的類型是抽象類型Animal,因此不能直接調(diào)用由派生類提供的方法,而必須使用數(shù)據(jù)類型轉(zhuǎn)換:((Chicken)animalArray[1]).LayEgg();ArrayList集合是System.Object對象的集合(通過多態(tài)性賦給Anima!對象),陰U必須對所有的項進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換:((Animal)animalArrayList[0]).Feed();((Chicken)animalArrayList[1]).LayEgg();代碼的剩余部分利用的ー些ArrayList集合功能超出了Array集合的功能范圍。首先,可以使用Remove。和RemoveAt。方法刪除項,這兩個方法是在ArrayList類中實現(xiàn)的IList接口的一部分。它們分別根據(jù)項目引用或索引把項從數(shù)組中刪除。在本例中,我們使用后ー個方法刪除添加到列表中的第一項,即Name屬性為Hayley的Cow對象:animalArrayList.RemoveAt(0);另外,還可以使用:animalArrayList.Remove(myCow2);因為這個對象已經(jīng)有一個本地引用了,所以可以通過Add()添加對數(shù)組的ー個現(xiàn)有引用,而不是創(chuàng)建一個新對象。無論采用哪種方式,集合中唯一剩下的項是Chicken對象,可以用下面的方式訪問它:((Animal)animalArrayList[0]).Feed();對ArrayList對象中的項進(jìn)行修改,使數(shù)組中剩下N個項,其實現(xiàn)方式與保留從0-N-1的索引相同。例如,刪除索引為〇的項,會使其他項在數(shù)組中移動ー個位置,所以應(yīng)使用索引0來訪問Chicken對象,而不是I。不再有索引為1的項了(因為集合中最初只有兩個項),所以如果試圖執(zhí)行下面的代碼,就會拋出異常:((Animal)animalArrayList[1]).Feed();ArrayList集合可以用AddRange。方法一次添加好幾個項。這個方法接受帶有ICollection接口的任何對象,包括前面的代碼所創(chuàng)建的animalArray數(shù)組:animalArrayList.AddRange(animalArray);為了確定這是否有效,可以試著訪問集合中的第三項,它將是animalArray中的第二項:((Chicken)animalArrayList[2]).LayEgg();AddRange。方法不是ArrayList提供的任何接口的一部分。這個方法專用于ArrayList類,論證了可以在集合類中執(zhí)行定制操作,而不僅僅是前面介紹的接口要求的操作。這個類還提供了其他有趣的方法,如InsertRange。,它可以把數(shù)組對象插入到列表中的任何位置,還有用于給數(shù)組排序和重新排序的方法。最后,再回過頭來看看對同一個對象進(jìn)行多個引用。使用IList接口中的!ndexOf。方法可以看出,myCowl(最初添加到animalArray中的ー個對象)現(xiàn)在是animalArrayList集合的一部分,它的索引如下:Console.WriteLine(nTheanimalcalled{0}isatindex{1}.n,myCowl.Name,animalArrayList.IndexOf(myCowl));例如,接下來的兩行代碼通過對象引用重新命名了對象,并通過集合引用顯示了新名稱:myCowl.Name=nJanice";Console.WriteLine("Theanimalisnowcalled{0}.",((Animal)animalArrayList[1]).Name);定義集合前面介紹了使用高級集合類能完成什么任務(wù),下面討論如何創(chuàng)建自己的、強(qiáng)類型化的集合。ー種方式是手動執(zhí)行需要的方法,但這比較花時間,在某些情況下也非常復(fù)雜。我們還可以從ー個類中派生自己的集合,例如System.Collections.CollectionBase類,這個抽象類提供了集合類的許多實現(xiàn)方式。這是推薦使用的方式。CollectionBase類有接口【Enumerable、ICollection和IList,但只提供了一些要求的執(zhí)行代碼,特別是IList的Clear。和RemoveAt。方法,以及!Collection的Count屬性。如果要使用提供的功能,就需要自己執(zhí)行其他代碼。為了便于完成任務(wù),CollectionBase提供了兩個受保護(hù)的屬性,它們可以訪問存儲的對象本身。我們可以使用List和!nnerList,List可以通過!List接口訪問項,InnerList則是用于存儲項的ArrayList對象。例如,存儲Animal對象的集合類可以定義如下(稍后介紹ー個比較完整的執(zhí)行代碼):publicclassAnimals:CollectionBase(publicvoidAdd(AnimalnewAnimal)(List.Add(newAnimal);)publicvoidRemove(AnimaloldAnimal)(List.Remove(oldAnimal);)publicAnimals()())其中,Add。和Remove。方法實現(xiàn)為強(qiáng)類型化的方法,使用IList接口中用于訪問項的標(biāo)準(zhǔn)Add。方法。該方法現(xiàn)在只用于處理Anima!類或派生于Animal的類,而前面介紹的ArrayList執(zhí)行代碼可處理任何對象。CollectionBase類可以對派生的集合使用foreach語法。例如,可以使用下面的代碼:Console.WriteLine("UsingcustomcollectionclassAnimals:");AnimalsanimalCollection=newAnimals();animalCollection.Add(newCow("Sarah"));foreach(AnimalmyAnimalinanimalCollection)(Console.WriteLine("New{0}objectaddedtocustomcollection,"+"Name={1}",myAnimal.ToString(),myAnimal.Name);)但不能使用下面的代碼:animalCollection[0].Feed();要以這種方式通過索引來訪問項,就需要使用索引符。索引符索引符(indexer)是一種特殊類型的屬性,可以把它添加到ー個類中,以提供類似于數(shù)組的訪問。實際上,可以通過索引符提供更復(fù)雜的訪問,因為我們可以用方括號語法定義和使用復(fù)雜的參數(shù)類型。它最常見的一個用法是對項執(zhí)行簡單的數(shù)字索引。在Animal對象的Animals集合中添加一個索引符,如下所示:publicclassAnimals:CollectionBase{publicAnimalthis[intanimallndex]getreturn(Animal)List[animallndex];}set(List[animallndex]=value;)}}this關(guān)鍵字與方括號中的參數(shù)一起使用,但這看起來類似于其他屬性。這個語法是富有邏輯的,因為在訪問索引符時,將使用對象名,后跟放在方括號中的索引參數(shù)(例如MyAnimals|0])o這段代碼對しist屬性使用ー個索引符(即在IList接口上,可以訪問CollectionBase中的ArrayList,ArrayList存儲了項):return(Animal)List[animallndex];這里需要進(jìn)行顯式數(shù)據(jù)類型轉(zhuǎn)換,因為!List.List屬性返回ー個System.Object對象。注意,我們?yōu)檫@個索引符定義了一個類型。使用該索引符訪問某項時,就可以得到這個類型,即可以編寫下述代碼:animaICollection[0].Feed();而不是:((Animal)animalCollection[0]).Feed();這是強(qiáng)類型化的定制集合的另ー個方便特性。下面擴(kuò)展上一個示例,實踐一下該特性。試試看:實現(xiàn)Animals集合(1)在目錄C:\BegVCSharp\Chapterl1'下倉リ建一個新控制臺應(yīng)用程序ChllEx02o(2)在SolutionExplorer窗口中右擊項目名,選擇AddIExistingItem選項。(3)從目錄C:\BegVCSharp\Chapterll\ChllEx01\ChllExOl下選擇Animal.cs、Cow.cs和Chicken.cs文件,單擊Add按鈕。(4)修改這3個文件中的名稱空間聲明,如下所示:namespaceChllExO2(5)添加一個新類Animalso(6)修改Animals.cs中的代碼,如下所示:usingSystem;usingSystem.Collections;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;?endregionnamespaceChllExO2(publicclassAnimals:CollectionBase{publicvoidAdd(AnimalnewAnimal)(List.Add(newAnimal);}publicvoidRemove(AnimalnewAnimal)(List.Remove(newAnimal);publicAnimals()publicAnimalthis[intanimalIndex]get(return(Animal)List[animalIndex];)set{List[animalIndex]=value;)})}(7)修改Program.es,如下所示:staticvoidMain(string[]args)(AnimalsanimalCollection=newAnimals();animalCollection.Add(newCow("Jack"));animalCollection.Add(newChicken("Vera"));foreach(AnimalmyAnimalinanimalCollection)(myAnimal.Feed();)Console.ReadKey();}(8)}(8)執(zhí)行應(yīng)用程序圖11-2示例的說明這個示例使用上一節(jié)詳細(xì)介紹的代碼,實現(xiàn)類Animals中強(qiáng)類型化的Anima!對象集合。Main。中的代碼僅實例化了一個Animals對象animalCollection,添加了兩個項(它們分別是Cow和Chicken的實例),再使用foreach循環(huán)調(diào)用這兩個對象繼承于基類Anima!的Feed。方法。給CardLib添加Cards集合第!0章創(chuàng)建了一個類庫項目ChlOCardLib,它包含ー個表示撲克牌的Card類和ー個表示一幅撲克牌的Deck類,這個Deck類是Card類的集合,且實現(xiàn)為ー個簡單的數(shù)組。本章給這個庫添加一個新類,并把類庫重命名為ChllCardLib。這個新類Cards是Card對象的ー個定制集合,并擁有本章前面介紹的各種功能。在目錄C:\BegVCSharp\Chapterl1、下創(chuàng)建一個新的類庫ChiICardLib,再從ProjectIAddExistingItem中選擇C:\BegVCSharp\ChapterlO\ChlOCardLib\ChlOCardLib目錄下的Card.cs、Deck.cs、Suit.cs和Rank.cs文件,把它們添加到項目中。與第10章介紹的這個項目的上一個版本相同,這里也不使用標(biāo)準(zhǔn)的“試試看”格式介紹這些變化。讀者可以在本章的下載代碼中打開這個項目的版本,直接?xùn)丝创a。注意:在把源文件從ChlOCardLib復(fù)制到ChllCardLib中時,必須修改名稱空間聲明,以引用ChllCardLib0對用于測試的ChlOCardLib控制臺應(yīng)用程序也要進(jìn)行這個修改。本章下載代碼中的ー個項目包含了對ChllCardLib進(jìn)行的各種擴(kuò)展。其代碼放在各個區(qū)段中,如果讀者要實踐一下,可以取消這些區(qū)段的注釋。如果要H己創(chuàng)建這個項目,就應(yīng)添加一個新類Cards,修改Cards.cs中的代碼,如下所示:usingSystem;usingSystem.Collections;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;namespaceChllCardLib(publicclassCards:CollectionBase{publicvoidAdd(CardnewCard)(List.Add(newCard);}publicvoidRemove(CardoldCard)(List.Remove(oldCard);}publicCards()publicCardthis[intcardindex]getreturn(Card)List[cardindex];)set{List[cardindex]=value;}}//UtilitymethodforcopyingcardinstanceintoanotherCardsinstance//-usedinDeck.Shuffle().Thisimplementationassumethatsourceand//targetcollectionsarethesamesize.publicvoidCopyTo(Cardstargetcards){for(intindex=0;index<this.Count;index++)(targetcards[index]=this[index];})//ChecktoseeiftheCardscollectioncontainsaparticularcard.//ThiscallstheContainsmethodoftheArrayListforthecollection.//whichweaccessthroughtheInnerListproperty.publicboolContains(Cardcard)(returnInnerList.Contains(card);)}).然后,需要修改Deck.cs,以利用這個新集合,而不是數(shù)組:usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;namespaceChiICardLib{publicclassDeck{privateCardscards=newCards();publicDeck()(//lineofcoderemovedhere.for(intsuitVal=0;suitVal<4;suitVal++)(for(intrankVal=1;rankVal<14;rankVal++)cards.Add(newCard((Suit)suitVal,(Rank)rankVal));
publicCardGetCard(intcardNum)(if(cardNum>=0&&cardNum<=51)returncards[cardNum];elsethrow(newSystem.ArgumentOutOfRangeException("cardNum”,cardNum,HValuemustbebetween0and51.H));}publicvoidShuffle()(CardsnewDeck=newCards();bool[]assigned=newbool[52];RandomsourceGen=newRandom();for(inti=0;i<52;i++){intsourceCard=0;boolfoundCard=false;while(foundCard==false)(sourceCard=sourceGen.Next(52);false)if(assigned[sourceCard]==false)foundCardtruefoundCardtrue;}assigned[sourceCard]=true;newDeck.Add(cards[sourceCard]);}newDeck.CopyTo(cards,0);})}在此不需要進(jìn)行很多修改。其中的大多數(shù)修改都涉及到改變洗牌邏輯,才能把Cards中隨機(jī)的ー張牌添加到新Cards集合newDeck的開頭,而不是把cards集合中順序位置的ー張牌添加newDeck集合的隨機(jī)位置上。ChlOCardLib解決方案的客戶控制臺應(yīng)用程序ChlOCardClient可以使用這個新庫得到與以前相同的結(jié)果,因為Deck的方法簽名沒有改變。這個類庫的客戶程序現(xiàn)在可以使用Cards集合類,而不是依賴于Card對象數(shù)組,例如,在撲克牌游戲應(yīng)用程序中定義一手牌。關(guān)鍵字值集合和【Dictionary除了IList接口外,集合還可以實現(xiàn)類似的【Dictionary接口,允許項通過關(guān)鍵字值(如字符串名)進(jìn)行索引,而不是通過ー個索引。這也可以使用索引符來完成,但這次的索引符參數(shù)是與存儲的項相關(guān)聯(lián)的關(guān)鍵字,而不是int索引,這樣集合的用戶友好性就更高了。與索引的集合一樣,可以使用一個基類簡化IDictionaiy接口的實現(xiàn),這個基類就是DictionaryBase,它也實現(xiàn)!Enumerable和!Collection接口,提供了對任何集合都相同的集合處理功能。DictionaryBase與CollectionBaseー樣,實現(xiàn)通過其支持的接口獲得的一些成員(但不是全部成員)。DictionaryBase也執(zhí)行Clear。和Count。,但不執(zhí)行RemoveAt。。這是因為RemoveAt。是IList接口上的ー個方法,不是いictionary接口上的一個方法。但是,Dictionary有一個Remove。方法,這是ー個應(yīng)在基于DictionaryBase的定制集合類上執(zhí)行的方法。下面的代碼是上一節(jié)Animals類的另ー個版本,這次該類派生于DictionaryBase。下面代碼包括Add。、Remove。和一個通過關(guān)鍵字訪問的索引符的執(zhí)行代碼:publicclassAnimals:DietionaryBase{publicvoidAdd(stringnewIDzAnimalnewAnimal){Dictionary.Add(newIDznewAnimal);)publicvoidRemove(stringanimallD){Dictionary.Remove(animallD);)publicAnimals(){)publicAnimalthis[stringanimallD]{get(return(Animal)Dictionary[animallD];setDictionary[animalID]=value;))這些成員
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 公司讀書會策劃方案
- 公司租車活動方案
- 公司文娛游戲活動方案
- 公司新人培養(yǎng)活動方案
- 公司福利房活動方案
- 公司生日小活動方案
- 公司組織電影活動方案
- 公司改善之星活動方案
- 公司新年patty活動方案
- 公司紀(jì)念活動方案
- 漿料回收工藝及流程
- QSY 1643-2013安全目視化管理導(dǎo)則培訓(xùn)課件
- 人教版高中數(shù)學(xué)選修2-3全部教案
- 學(xué)校中層干部選拔考試教育教學(xué)管理知識試題題庫(包含:名詞解釋、簡答題、論述題、案例分析)
- 港口規(guī)劃與布置課程設(shè)計
- GB/T 799-2020地腳螺栓
- GB/T 213-2003煤的發(fā)熱量測定方法
- GB/T 19411-2003除濕機(jī)
- GB/T 15683-2008大米直鏈淀粉含量的測定
- 幼兒園大班畢業(yè)典禮教師詩朗誦
- 【部編人教版】貴州省銅仁市2021-2022年八年級下期末數(shù)學(xué)試卷
評論
0/150
提交評論