C#面向?qū)ο缶幊蘝第1頁(yè)
C#面向?qū)ο缶幊蘝第2頁(yè)
C#面向?qū)ο缶幊蘝第3頁(yè)
C#面向?qū)ο缶幊蘝第4頁(yè)
C#面向?qū)ο缶幊蘝第5頁(yè)
已閱讀5頁(yè),還剩50頁(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)介

5.1繼承

繼承是重要的代碼重用技術(shù),更重要的繼承反映了許多現(xiàn)實(shí)世界問(wèn)題的內(nèi)在特點(diǎn)。

C#中的繼承只是單繼承,C#不支持多繼承機(jī)制,因?yàn)楸M管多繼承帶來(lái)許多靈活性,但也會(huì)引發(fā)一些不確定性,給編程和系統(tǒng)運(yùn)行帶來(lái)麻煩。

5.5.1繼承的定義在現(xiàn)有的類(lèi)(稱(chēng)為直接基類(lèi))的基礎(chǔ)上建立新類(lèi)(稱(chēng)為派生類(lèi))的處理過(guò)程稱(chēng)為繼承。在創(chuàng)建新類(lèi)的過(guò)程中,直接基類(lèi)不作任何改變,派生類(lèi)繼承其直接基類(lèi)的成員。繼承意味著派生類(lèi)隱式包含它的直接基類(lèi)的所有成員,但不能繼承基類(lèi)的實(shí)例構(gòu)造函數(shù)、靜態(tài)構(gòu)造函數(shù)、析構(gòu)函數(shù)。通常,繼承是指顯式繼承,由于C#只支持單繼承,因此基類(lèi)只有一個(gè)。繼承(續(xù))繼承(續(xù))從基類(lèi)繼承或派生出一個(gè)子類(lèi)的語(yǔ)法格式為:class派生類(lèi)名:基類(lèi)名{派生類(lèi)代碼}

其中,冒號(hào)“:”的含義是“派生于”。在C#面向?qū)ο缶幊陶Z(yǔ)言中,類(lèi)的繼承機(jī)制有以下特征:(1)派生類(lèi)直接繼承其基類(lèi)的成員,并隱式包含其直接基類(lèi)中除構(gòu)造函數(shù)和析構(gòu)函數(shù)外的所有成員。

繼承(續(xù))

(2)繼承具有可傳遞性。如果A類(lèi)派生出B類(lèi),B類(lèi)派生出C類(lèi),則C類(lèi)會(huì)繼承A類(lèi)和B類(lèi)中所有的類(lèi)成員(不含構(gòu)造函數(shù)和析構(gòu)函數(shù))。(3)派生類(lèi)可在其基類(lèi)的基礎(chǔ)上添加新成員,但不能刪除所繼承的成員定義。(4)在派生類(lèi)中,可以通過(guò)定義與所繼承的基類(lèi)成員具有相同名稱(chēng)的新成員來(lái)隱藏所繼承的成員,從而使所繼承的成員在派生類(lèi)的實(shí)例中不可訪問(wèn)。(5)派生類(lèi)與其基類(lèi)之間存在隱式轉(zhuǎn)換關(guān)系,因此,對(duì)派生類(lèi)的實(shí)例引用可以看作是對(duì)其基類(lèi)的實(shí)例引用?!纠?-1】類(lèi)繼承時(shí)隱藏同名成員的應(yīng)用示例。usingSystem;namespaceSchool{ publicclassStudent { protectedstringname; protectedintid; publicStudent() {} publicStudent(stringstr,int_id) { name=str; id=_id; }

繼承(續(xù))

繼承(續(xù))

publicvoidPrintBase(){Console.WriteLine("在基類(lèi):Student."); } publicvoidFindInfo(int_id) { if(_id==id) Console.WriteLine("{0}isastudent.",Name); } }publicclassCollegeStudent:Student {stringdepartment;newstring_name;//隱藏同名字段成員

繼承(續(xù))

publicCollegeStudent(stringdept,stringstr,int_id) { department=dept; name=str; id=_id; }publicvoidPrintDerived() {Console.WriteLine("在派生類(lèi):CollegeStudent."); } publicnewvoidFindInfo(int_id)//隱藏同名方法

{ if(_id==id) Console.WriteLine("{0}isastudentinthe{1}Department.",name,department); } }

繼承(續(xù))publicclassTest{publicstaticvoidMain() {Studentstudent=newStudent("李四",0518277);CollegeStudentcollegeStudent=newCollegeStudent(“計(jì)算機(jī)”,“張三",0518288); student.FindInfo(0518277); student.PrintBase(); collegeStudent.FindInfo(0518288); collegeStudent.PrintBase(); collegeStudent.PrintDerived(); }}}

繼承(續(xù))

派生類(lèi)繼承基類(lèi)的成員,有利于減少維護(hù)的工作量。在實(shí)際的軟件項(xiàng)目開(kāi)發(fā)中,許多子程序和算法都被反復(fù)使用,對(duì)常用類(lèi)庫(kù)的需求很大,因此,一些軟件公司開(kāi)發(fā)出了很多類(lèi)庫(kù)。.NET中提供了一個(gè)C#程序設(shè)計(jì)使用的類(lèi)庫(kù),其中System.Object是最基本的類(lèi),所有其他的類(lèi)都直接或間接地派生于這個(gè)類(lèi),派生出來(lái)的類(lèi)稱(chēng)為子類(lèi),被繼承的類(lèi)稱(chēng)為父類(lèi)。因此,通過(guò)繼承,類(lèi)庫(kù)中的類(lèi)組成了一個(gè)樹(shù)狀層次結(jié)構(gòu)。

繼承(續(xù))

5.1.2重寫(xiě)

重寫(xiě)方法用相同的簽名重寫(xiě)所繼承的虛擬方法。最常用的重寫(xiě)就是對(duì)接口方法的實(shí)現(xiàn)。接口中一般只是對(duì)方法進(jìn)行了聲明,而在使用接口時(shí),則需要實(shí)現(xiàn)接口中聲明的所有方法。

5.2抽象和密封

抽象類(lèi)和密封類(lèi)是C#中兩個(gè)特殊的類(lèi)類(lèi)型。抽象類(lèi)用于提供多個(gè)派生類(lèi)可共享的基類(lèi)的公共定義,密封類(lèi)用于控制類(lèi)的派生。5.2.1抽象類(lèi)從許多事物中舍棄個(gè)別的、非本質(zhì)的特征,而抽取共同的、本質(zhì)性的特征,就是抽象的過(guò)程。通過(guò)使用抽象,分析員不需要了解和描述復(fù)雜的問(wèn)題域中的所有事物,而只需要分析、研究其中與系統(tǒng)目標(biāo)有關(guān)的事物及其本質(zhì)特征,通過(guò)舍棄個(gè)體事物在細(xì)節(jié)上的差異,并抽取這些事物的共同特征,從而可以得到事物的抽象概念。抽象和密封(續(xù))

抽象是面向?qū)ο蠓椒ㄖ惺褂米顝V泛的原則。抽象包括過(guò)程抽象和數(shù)據(jù)抽象兩個(gè)方面。過(guò)程抽象是指對(duì)于任何一個(gè)完成確定功能的操作序列,使用者都可以把它看作是一個(gè)單一的實(shí)體,盡管實(shí)際上它可能是由一系列更低級(jí)的操作完成的。數(shù)據(jù)抽象是指根據(jù)施加于數(shù)據(jù)之上的操作來(lái)定義數(shù)據(jù)類(lèi)型,并限定數(shù)據(jù)的值只能由這些操作來(lái)修正。數(shù)據(jù)抽象是面向?qū)ο蠓治龅暮诵脑瓌t,它強(qiáng)調(diào)把數(shù)據(jù)(屬性)和操作(服務(wù))結(jié)合為一個(gè)不可分的系統(tǒng)單位(對(duì)象),對(duì)象的外部只需要知道它做什么,而不必知道如何做。抽象和密封(續(xù))

抽象類(lèi)是基類(lèi)的一種特殊類(lèi)型,它除了擁有普通的類(lèi)成員之外,還具有抽象類(lèi)成員。抽象類(lèi)中的方法和屬性只有聲明(使用關(guān)鍵字abstract),而沒(méi)有實(shí)現(xiàn)部分。由于對(duì)實(shí)例而言,沒(méi)有實(shí)現(xiàn)的成員是不合法的,因此,抽象類(lèi)不能實(shí)例化。抽象類(lèi)既可以提供抽象方法,也可以提供非抽象方法。抽象類(lèi)不能實(shí)例化,必須通過(guò)繼承由派生類(lèi)實(shí)現(xiàn)其抽象方法,因此,不能對(duì)抽象類(lèi)使用new關(guān)鍵字,也不能將其密封。如果派生類(lèi)沒(méi)有實(shí)現(xiàn)所有的抽象方法,則此派生類(lèi)也必須聲明為抽象類(lèi)。另外,在派生類(lèi)實(shí)現(xiàn)抽象方法時(shí),應(yīng)對(duì)此方法用修飾符override加以修飾。

抽象和密封(續(xù))5.2.2密封類(lèi)

如果所有的類(lèi)都可以被繼承,就很容易導(dǎo)致繼承的濫用,使類(lèi)的層次結(jié)構(gòu)變得復(fù)雜,從而使開(kāi)發(fā)人員對(duì)類(lèi)的理解和使用變得困難,為了避免這種情況,C#提出了密封類(lèi)的概念。密封可以用來(lái)限制類(lèi)的擴(kuò)展和繼承,如果密封了某個(gè)類(lèi),則其他類(lèi)不能從此類(lèi)繼承;如果密封了某個(gè)成員,則派生類(lèi)不能對(duì)此成員進(jìn)行重寫(xiě)操作,即密封可以防止對(duì)類(lèi)的成員進(jìn)行繼承或重寫(xiě)。在默認(rèn)情況下,不應(yīng)密封類(lèi)的成員。抽象和密封(續(xù))在C#中使用的類(lèi)如果滿足如下條件,則應(yīng)將其密封:(1)類(lèi)是靜態(tài)類(lèi)。(2)類(lèi)包含帶有安全敏感信息的受保護(hù)成員。(3)類(lèi)繼承多個(gè)虛成員,并且密封每個(gè)成員的開(kāi)發(fā)和測(cè)試的開(kāi)銷(xiāo)明顯大于密封整個(gè)類(lèi)。(4)類(lèi)是一個(gè)要求使用反射(一種動(dòng)態(tài)程序的組織和管理技術(shù))進(jìn)行快速搜索的屬性。密封屬性可提高反射在檢索屬性時(shí)的性能。抽象和密封(續(xù))

在C#中聲明抽象類(lèi)時(shí)需要使用sealed關(guān)鍵字,語(yǔ)法格式如下:訪問(wèn)修飾符sealedclass類(lèi)名:基類(lèi)或接口{類(lèi)成員}說(shuō)明:(1)密封類(lèi)不能作為基類(lèi)被繼承,但它可以繼承其他類(lèi)或接口。(2)在密封類(lèi)中不能聲明受保護(hù)成員或虛成員,因?yàn)槭鼙Wo(hù)成員只能從派生類(lèi)進(jìn)行訪問(wèn),而虛成員只能在派生類(lèi)中重寫(xiě)。(3)密封類(lèi)的不可繼承性使其不能聲明為抽象的,即sealed修飾符不能與abstract修飾符同時(shí)使用。

5.3多態(tài)

多態(tài)性是一項(xiàng)允許將父對(duì)象設(shè)置為一個(gè)或多個(gè)子對(duì)象相等的技術(shù),引用之后,父對(duì)象就可以動(dòng)態(tài)地根據(jù)當(dāng)前引用的子對(duì)象的特性以不同的方式運(yùn)作。也可以這樣理解,多態(tài)就是“多種形式”,它意味著可以利用動(dòng)態(tài)綁定技術(shù),用具有相同名稱(chēng)的方法來(lái)調(diào)用方法的不同具體實(shí)現(xiàn)。多態(tài)性是面向?qū)ο蟮某绦蛟O(shè)計(jì)語(yǔ)言的基本特征之一。

多態(tài)(續(xù))

5.3.1多態(tài)定義

同一操作作用于不同的對(duì)象,可以有不同的解釋?zhuān)a(chǎn)生不同的執(zhí)行結(jié)果,這就是多態(tài)性。多態(tài)性通過(guò)派生類(lèi)重載基類(lèi)中的虛函數(shù)來(lái)實(shí)現(xiàn),虛函數(shù)一般virtual來(lái)修飾。多態(tài)(續(xù))C#支持兩種類(lèi)型的多態(tài)性:(1)編譯時(shí)的多態(tài)性:編譯時(shí)的多態(tài)性是通過(guò)重載來(lái)實(shí)現(xiàn)的。對(duì)于非虛的成員來(lái)說(shuō),系統(tǒng)在編譯時(shí)根據(jù)傳遞的參數(shù)、返回值的類(lèi)型等信息決定實(shí)現(xiàn)何種操作。(2)運(yùn)行時(shí)的多態(tài)性:運(yùn)行時(shí)的多態(tài)性是指直到系統(tǒng)運(yùn)行時(shí),才根據(jù)實(shí)際情況決定實(shí)現(xiàn)何種操作。在C#中,運(yùn)行時(shí)的多態(tài)性通過(guò)虛成員實(shí)現(xiàn)。

多態(tài)(續(xù))5.3.2多態(tài)性應(yīng)用

多態(tài)性是類(lèi)為方法(這些方法以相同的名稱(chēng)調(diào)用)提供不同實(shí)現(xiàn)方式的能力。多態(tài)性允許對(duì)類(lèi)的某個(gè)方法進(jìn)行調(diào)用,而無(wú)需考慮此方法所提供的特定實(shí)現(xiàn)。例如,名為Road的類(lèi)調(diào)用另一個(gè)類(lèi)的Drive方法,這“另一個(gè)類(lèi)”可能是SportsCar或SmallCar,但兩者都提供Drive方法。雖然Drive方法的實(shí)現(xiàn)因類(lèi)的不同而異,但Road類(lèi)仍可以調(diào)用它,其提供的結(jié)果可由Road類(lèi)使用和解釋。多態(tài)(續(xù))1.接口的多態(tài)性應(yīng)用接口本質(zhì)上是類(lèi)需要如何響應(yīng)的定義,它描述了類(lèi)需要實(shí)現(xiàn)的方法、屬性和事件,以及每個(gè)成員需要接收和返回的參數(shù)類(lèi)型,但將這些成員的特定實(shí)現(xiàn)由派生類(lèi)完成。組件編程中的一項(xiàng)強(qiáng)大技術(shù)就是能夠在一個(gè)對(duì)象上實(shí)現(xiàn)多個(gè)接口,每個(gè)接口由一些緊密聯(lián)系的方法、屬性和事件組成。組件可以通過(guò)接口為其他組件提供功能,開(kāi)發(fā)人員最常使用的組件功能是組件類(lèi)本身的成員。然而,包含大量成員的組件使用起來(lái)可能比較困難,可以考慮將組件的某些功能分解出來(lái),作為單獨(dú)實(shí)現(xiàn)的接口。多態(tài)(續(xù))

可以通過(guò)定義和實(shí)現(xiàn)附加接口增量地將功能添加到組件中,其優(yōu)點(diǎn)是:(1)簡(jiǎn)化了設(shè)計(jì)過(guò)程,需要增加功能時(shí),只需在組件中添加實(shí)現(xiàn)這些功能的方法即可。(2)簡(jiǎn)化了兼容性的維護(hù),組件的新版本可以在添加新接口的同時(shí)繼續(xù)提供現(xiàn)有接口。2.繼承的多態(tài)性應(yīng)用多個(gè)不同的類(lèi)可以從單個(gè)基類(lèi)繼承。通過(guò)繼承,類(lèi)可以接收基類(lèi)的所有方法、屬性和事件,從而可以根據(jù)需要來(lái)實(shí)現(xiàn)附加成員,并可以重寫(xiě)基成員以提供不同的實(shí)現(xiàn)。多態(tài)(續(xù))

C#通過(guò)繼承提供多態(tài)性,對(duì)于小規(guī)模開(kāi)發(fā)任務(wù)而言,這是一個(gè)功能強(qiáng)大的機(jī)制,但對(duì)于大規(guī)模系統(tǒng),通常會(huì)存在問(wèn)題。過(guò)分強(qiáng)調(diào)繼承驅(qū)動(dòng)的多態(tài)性一般會(huì)導(dǎo)致資源大規(guī)模地從編碼轉(zhuǎn)移到設(shè)計(jì),這對(duì)于縮短總的開(kāi)發(fā)時(shí)間沒(méi)有任何幫助。使用繼承首先是為了向現(xiàn)有基類(lèi)添加功能,若從經(jīng)過(guò)完全調(diào)試的基類(lèi)框架開(kāi)始,將方法增量地添加到基類(lèi)而不會(huì)中斷版本,則程序員的工作效率將大大提高。多態(tài)(續(xù))3.抽象類(lèi)的多態(tài)性應(yīng)用抽象類(lèi)本身不能實(shí)例化,它必須被繼承,其部分或全部成員的實(shí)現(xiàn)由繼承類(lèi)提供。已實(shí)現(xiàn)的成員仍可被重寫(xiě)。當(dāng)需要一組相關(guān)組件包含一組具有相同功能的方法,但同時(shí)要求在其他方法實(shí)現(xiàn)中具有靈活性時(shí),可以使用抽象類(lèi)。需要進(jìn)行版本時(shí),也可以使用抽象類(lèi)。

5.4泛型

泛型可以使類(lèi)、結(jié)構(gòu)、接口、委托和方法通過(guò)它們存儲(chǔ)和操縱的數(shù)據(jù)的類(lèi)型被參數(shù)化。軟件設(shè)計(jì)中涉及很多算法和數(shù)據(jù)結(jié)構(gòu),泛型的主要思想就是將算法和數(shù)據(jù)結(jié)構(gòu)完全分離開(kāi)來(lái),使一次定義的算法能夠作用于多種數(shù)據(jù)結(jié)構(gòu),從而實(shí)現(xiàn)代碼的高度可重用性。

泛型(續(xù))

5.4.1泛型的引入

2005年底微軟公司正式發(fā)布了C#2.0,與C#1.x相比,這一版本增加了很多新特性,其中最重要的是對(duì)泛型的支持,可以通過(guò)泛型定義類(lèi)型安全的數(shù)據(jù)結(jié)構(gòu),而無(wú)須使用實(shí)際的數(shù)據(jù)類(lèi)型,這能得到更高質(zhì)量的代碼并顯著提高系統(tǒng)性能。泛型在功能上類(lèi)似于C++的模板。泛型(續(xù))

在編寫(xiě)程序時(shí),經(jīng)常遇到兩個(gè)模塊的功能非常相似,如一個(gè)模塊用于處理int類(lèi)型的數(shù)據(jù),而另一個(gè)則用于處理string類(lèi)型的數(shù)據(jù),但方法的參數(shù)類(lèi)型不同使得程序設(shè)計(jì)人員只能分別編寫(xiě)多個(gè)不同的方法處理每個(gè)數(shù)據(jù)類(lèi)型。如果可以在方法中傳入通用的數(shù)據(jù)類(lèi)型,就會(huì)解決這一問(wèn)題,這就是泛型。所謂泛型,即通過(guò)參數(shù)化類(lèi)型來(lái)實(shí)現(xiàn)在同一方法中操作多種數(shù)據(jù)類(lèi)型。例如,下面的代碼的功能是實(shí)現(xiàn)一個(gè)棧,這個(gè)棧只能處理int數(shù)據(jù)類(lèi)型。

泛型(續(xù))5.4.2泛型的創(chuàng)建和使用

1.創(chuàng)建泛型泛型提供了一種新的創(chuàng)建類(lèi)型的機(jī)制,使用泛型創(chuàng)建的類(lèi)型將帶有類(lèi)型形參。下面的示例聲明了一個(gè)帶有類(lèi)型形參T的泛型Stack類(lèi),其中類(lèi)型形參在<>分隔符中指定并放置在類(lèi)名后。Stack<T>的實(shí)例的類(lèi)型由創(chuàng)建時(shí)所指定的類(lèi)型確定,實(shí)例將存儲(chǔ)這個(gè)類(lèi)型的數(shù)據(jù)而不進(jìn)行數(shù)據(jù)類(lèi)型轉(zhuǎn)換。類(lèi)型形參T只起占位符的作用,直到在使用時(shí)為其指定了實(shí)際類(lèi)型。例如:泛型(續(xù))public

class

Stack<T>{

T[]

items;

int

count;

public

void

Push(T

item){}public

T

Pop()

{}}泛型(續(xù))2.泛型類(lèi)用泛型來(lái)重寫(xiě)上述示例中的棧,用一個(gè)通用的數(shù)據(jù)類(lèi)型T來(lái)作為一個(gè)占位符,等待在實(shí)例化時(shí)用一個(gè)實(shí)際的數(shù)據(jù)類(lèi)型來(lái)代替。

publicclassStack<T>{

privateT[]m_item;

publicTPop(){}

publicvoidPush(Titem){}

publicStack(inti)

{

this.m_item=newT[i];

}}泛型(續(xù))3.泛型方法泛型不僅能作用于類(lèi),也可以單獨(dú)用在類(lèi)的方法上,并可以根據(jù)方法參數(shù)的類(lèi)型自動(dòng)適應(yīng)各種參數(shù),這樣的方法即為泛型方法。5.4.3泛型類(lèi)的成員1.泛型類(lèi)中的靜態(tài)成員變量2.泛型類(lèi)中的靜態(tài)結(jié)構(gòu)函數(shù)3.重載泛型類(lèi)中的方法4.重寫(xiě)泛型類(lèi)的方法

5.5接口

接口描述的是可屬于任何類(lèi)或結(jié)構(gòu)的一組相關(guān)功能。實(shí)現(xiàn)接口的類(lèi)或結(jié)構(gòu)要與接口的定義嚴(yán)格一致。接口可以從多個(gè)基接口繼承,但不能被實(shí)例化。接口好比一個(gè)模版,這個(gè)模版定義了對(duì)象必須實(shí)現(xiàn)的方法。

接口(續(xù))5.5.1定義接口

接口是包含一組虛方法的抽象類(lèi)型,其中每一種方法都有名稱(chēng)、參數(shù)和返回值。接口方法不能包含任何實(shí)現(xiàn),CLR允許接口包含事件、屬性、索引器、靜態(tài)方法、靜態(tài)字段、靜態(tài)構(gòu)造函數(shù)以及常數(shù),但不能包含任何實(shí)例成員。一個(gè)類(lèi)可以實(shí)現(xiàn)多個(gè)接口,當(dāng)一個(gè)類(lèi)繼承某個(gè)接口時(shí),它不僅要實(shí)現(xiàn)這個(gè)接口定義的所有方法,還要實(shí)現(xiàn)此接口從其他接口中繼承的所有方法。接口(續(xù))下面給出一個(gè)接口定義示例:publicinterfaceComparable{intCompareTo(objecto);}

接口(續(xù))抽象類(lèi)和接口的區(qū)別:(1)類(lèi)是對(duì)對(duì)象的抽象,可以把抽象類(lèi)理解為把類(lèi)當(dāng)作對(duì)象,抽象成的類(lèi)叫做抽象類(lèi)。接口只是一個(gè)行為的規(guī)范或規(guī)定。(2)抽象類(lèi)型可以選擇提供實(shí)現(xiàn)的詳細(xì)信息;而接口不能提供實(shí)現(xiàn)的任何詳細(xì)信息。(3)抽象類(lèi)不能被密封。(4)抽象類(lèi)實(shí)現(xiàn)的具體方法默認(rèn)為虛方法,但實(shí)現(xiàn)接口的類(lèi)中的接口方法默認(rèn)為非虛。(5)好的接口定義應(yīng)該具有專(zhuān)一的功能,而不是具有多功能,否則會(huì)造成接口污染。接口污染是指一個(gè)類(lèi)實(shí)現(xiàn)了一個(gè)接口中的某個(gè)方法,就必須實(shí)現(xiàn)該接口中的其他方法接口(續(xù))

(6)如果用抽象類(lèi)實(shí)現(xiàn)接口,則可以把接口中的方法映射到抽象類(lèi)中作為抽象方法,不必進(jìn)行具體實(shí)現(xiàn),而是在抽象類(lèi)的子類(lèi)中實(shí)現(xiàn)接口中的方法。(7)如果預(yù)計(jì)要?jiǎng)?chuàng)建組件的多個(gè)版本,則使用抽象類(lèi)。抽象類(lèi)通過(guò)提供簡(jiǎn)單的方法來(lái)控制組件版本。(8)如果要設(shè)計(jì)小而簡(jiǎn)練的功能模塊,則使用接口;如果設(shè)計(jì)大的功能單元,則使用抽象類(lèi)。(9)如果要在組件的所有實(shí)現(xiàn)之間提供通用的已實(shí)現(xiàn)功能,則使用抽象類(lèi)。(10)抽象類(lèi)主要用于關(guān)系密切的對(duì)象,而接口適用于為不相關(guān)的類(lèi)提供通用功能。5.5.2實(shí)現(xiàn)接口

5.6迭代器

迭代器是可以產(chǎn)生值的有序序列的一段代碼,通過(guò)它能按照指定的順序來(lái)訪問(wèn)一個(gè)集合中的所有元素。5.6.1定義迭代器迭代器是C#2.0中的新功能。迭代器使程序能夠在類(lèi)或結(jié)構(gòu)中支持foreach迭代,而不必實(shí)現(xiàn)整個(gè)IEnumerable接口。只需提供一個(gè)迭代器,即可遍歷類(lèi)中的數(shù)據(jù)結(jié)構(gòu)。當(dāng)編譯器檢測(cè)到迭代器時(shí),它將自動(dòng)生成IEnumerable或IEnumerable<T>接口的Current、MoveNext和Dispose方法。迭代器(續(xù))迭代器具有以下特點(diǎn):(1)迭代器可用作方法、運(yùn)算符或get訪問(wèn)器的代碼。(2)迭代器代碼使用yieldreturn語(yǔ)句依次返回每個(gè)元素,使用yieldbreak語(yǔ)句則可以終止迭代。其中,yield關(guān)鍵字用于指定返回的值。(3)可以在類(lèi)中實(shí)現(xiàn)多個(gè)迭代器,每個(gè)迭代器都必須像類(lèi)的成員一樣有唯一的名稱(chēng),并可以在foreach語(yǔ)句中被客戶端代碼調(diào)用,如“foreach(intxinSampleClass.Iterator2){}”。(4)迭代器的返回類(lèi)型必須為IEnumerable、IEnumerator、IEnumerable<T>或IEnumerator<T>。

迭代器(續(xù))

5.6.2實(shí)現(xiàn)迭代器

創(chuàng)建迭代器最常用的方法是對(duì)IEnumerable接口實(shí)現(xiàn)GetEnumerator方法。例如:

publicSystem.Collections.IEnumeratorGetEnumerator(){for(intj=0;j<max;j++){yieldreturnj;}}迭代器(續(xù))下面給出一個(gè)創(chuàng)建和使用迭代器的示例。//實(shí)現(xiàn)迭代器的類(lèi)publicclassYear:System.Collections.IEnumerable{string[]season={"Spring","Summer","Autumn","Winter"};publicSystem.Collections.IEnumeratorGetEnumerator(){for(inti=0;i<season.Length;i++){yieldreturnseason[i];}}}迭代器(續(xù))classProgram{staticvoidMain(string[]args){Yeary=newYear();//使用迭代器

foreach(stringsiny){System.Console.WriteLine(s+"\n");}}}5.7委托

委托是C#特有的成分,又被翻譯為代理、代表等。委托的功能類(lèi)似于C或C++中的函數(shù)指針,但與函數(shù)指針相比,委托能保持C#的面向?qū)ο蠛皖?lèi)型安全的先進(jìn)功能。委托可以將具有相同參數(shù)列表和返回類(lèi)型的方法組織起來(lái),以實(shí)現(xiàn)方法回調(diào)和事件處理。5.7.1定義委托

委托是一種引用方法的類(lèi)型。一旦為委托分配了方法,委托將與此方法具有完全相同的行為。與其他方法一樣,委托方法具有參數(shù)和返回值,例如:publicdelegateintPerformCalculation(intx,inty);

委托(續(xù))

與委托簽名(由返回類(lèi)型和參數(shù)組成)匹配的任何方法都可以分配給這個(gè)委托,這樣就可以通過(guò)編程的方式來(lái)更改方法調(diào)用,還可以向現(xiàn)有的類(lèi)中插入新代碼。將方法作為參數(shù)進(jìn)行引用的能力使委托成為定義回調(diào)方法的理想選擇。例如,可以向排序算法傳遞對(duì)比較兩個(gè)對(duì)象的方法的引用。

委托(續(xù))

5.7.2實(shí)例化委托例如:

publicdelegatevoidDel(stringmessage);publicclassExample{Deldel;//實(shí)例化委托

publicvoidmethod(stringmessage){

……}del=newDel(method);}

委托(續(xù))

5.7.3多重委托多重委托是由兩個(gè)或更多的其他委托構(gòu)成的委托。當(dāng)調(diào)用委托時(shí),可以調(diào)用多個(gè)方法,這又稱(chēng)為多路廣播。若要向委托的方法列表(調(diào)用列表)中添加額外的方法,只需使用加法運(yùn)算符或加法賦值運(yùn)算符(“+”或“+=”)添加兩個(gè)委托。5.7.4委托作為參數(shù)和返回值5.8匿名方法

構(gòu)造委托對(duì)象時(shí),如果使用匿名方法,則可以直接將方法的代碼塊作為參數(shù)傳給委托而不必調(diào)用方法,因此減少了實(shí)例化委托所需的編碼系統(tǒng)開(kāi)銷(xiāo)。匿名方法表達(dá)式由3部分組成,即關(guān)鍵字delegate、參數(shù)列表以及執(zhí)行代碼段,其中只有參數(shù)列表可以省略。其語(yǔ)法格式如下:delegate{參數(shù)列表}{

執(zhí)行代碼段}匿名方法(續(xù))

匿名方法表達(dá)式本身并不是一個(gè)完整的語(yǔ)句,只有將它賦值給一個(gè)委托對(duì)象才能構(gòu)成一個(gè)語(yǔ)句。在賦值給某個(gè)委托對(duì)象時(shí),要求匿名方法表達(dá)式與委托的定義保持一致,具體要求如下:(1)匿名方法表達(dá)式可以省略參數(shù)列表,其對(duì)應(yīng)的委托類(lèi)型可以包含任意多個(gè)參數(shù),但不能包含輸出參數(shù),而且不能在代碼段中使用這些參數(shù)。(2)如果匿名方法表達(dá)式指定了參數(shù)列表,則參數(shù)數(shù)量和參數(shù)類(lèi)型必須和委托中定義的一致,或者參數(shù)類(lèi)型可以隱式地轉(zhuǎn)換為委托中對(duì)應(yīng)的參數(shù)類(lèi)型。匿名方法(續(xù))

(3)匿名表達(dá)式的返回類(lèi)型(即其執(zhí)行代碼中return語(yǔ)句中的返回類(lèi)型)必須和委托定義的返回類(lèi)型相同或可以隱式地轉(zhuǎn)換為委托的返回類(lèi)型。如果存在多個(gè)return語(yǔ)句,則要求每個(gè)語(yǔ)句的返回類(lèi)型相同,并與委托的返回類(lèi)型相同。(4)如果委托定義的返回類(lèi)型是void,那么執(zhí)行代碼段沒(méi)有return語(yǔ)句,或是單獨(dú)使用不帶任何表達(dá)式的return語(yǔ)句。

5.9事件

事件是類(lèi)在發(fā)生其關(guān)注的事情時(shí)用來(lái)提供通知的一種方式,通常使用委托事件處理程序進(jìn)行聲明,并可以調(diào)用匿名方法來(lái)替代委托。5.9.1定義事件在C#中,事件實(shí)際上是委托的一種特殊形式,事件是專(zhuān)門(mén)用于處理過(guò)程的更為專(zhuān)業(yè)化的委托。定義事件的語(yǔ)法格式如下:

[訪問(wèn)修飾符]e

溫馨提示

  • 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)論