C網(wǎng)絡(luò)編程技術(shù)教程_第1頁(yè)
C網(wǎng)絡(luò)編程技術(shù)教程_第2頁(yè)
C網(wǎng)絡(luò)編程技術(shù)教程_第3頁(yè)
C網(wǎng)絡(luò)編程技術(shù)教程_第4頁(yè)
C網(wǎng)絡(luò)編程技術(shù)教程_第5頁(yè)
已閱讀5頁(yè),還剩101頁(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)介

C#網(wǎng)絡(luò)編程技術(shù)教程第三章C#面向?qū)ο缶幊?/p>

docin/sundae_mengC#網(wǎng)絡(luò)編程技術(shù)教程第三章C#面向?qū)ο缶幊蘢ocin/學(xué)習(xí)目標(biāo)理解面向?qū)ο蟮幕靖拍?。了解基本的面向?qū)ο蠓治?、設(shè)計(jì)方法,主要是UML中的類圖和序列圖。掌握C#中類的定義和實(shí)例化方法。掌握C#中繼承、多態(tài)、接口的實(shí)現(xiàn)方法。學(xué)習(xí)目標(biāo)理解面向?qū)ο蟮幕靖拍?。本章?nèi)容3.1面向?qū)ο蟮幕靖拍?.2類和對(duì)象3.3字段3.4方法3.5屬性與索引3.6委托與事件3.7繼承與多態(tài)3.8基于UML的系統(tǒng)分析與設(shè)計(jì)方法本章內(nèi)容3.1面向?qū)ο蟮幕靖拍?.1面向?qū)ο蟮幕靖拍?/p>

客觀世界是由各種各樣的對(duì)象組成的,如汽車、飛機(jī)、火車、人等。每種對(duì)象都有各自的內(nèi)部狀態(tài)和運(yùn)動(dòng)規(guī)律,不同對(duì)象之間的相互作用和聯(lián)系就構(gòu)成了各種不同的系統(tǒng)。將客觀世界中的對(duì)象模型化,形成一種計(jì)算機(jī)化的表示,并以此為基礎(chǔ)來(lái)分析和解決問(wèn)題便形成了面向?qū)ο蠹夹g(shù)。PeterCoad和EdwardYourdon提出了下列等式來(lái)說(shuō)明面向?qū)ο蠹夹g(shù)。面向?qū)ο?對(duì)象+分類+繼承+消息通信可以說(shuō),采用對(duì)象、類、繼承、消息這4個(gè)概念開發(fā)的軟件系統(tǒng)是面向?qū)ο蟮摹?.1面向?qū)ο蟮幕靖拍羁陀^世界是由各種3.1面向?qū)ο蟮幕靖拍?.對(duì)象在面向?qū)ο蠹夹g(shù)中,任何客觀事物都是對(duì)象,對(duì)象是對(duì)客觀事物的抽象。任何復(fù)雜的事物都可以通過(guò)對(duì)象的某種組合結(jié)構(gòu)構(gòu)成。復(fù)雜對(duì)象可由相對(duì)比較簡(jiǎn)單的對(duì)象以某種方式組成。對(duì)象由屬性和方法組成。屬性反映了對(duì)象的信息特征,而方法則定義改變屬性狀態(tài)的各種操作。因此,對(duì)象是屬性和方法的一個(gè)封裝體。通過(guò)封裝可以更好地隱蔽對(duì)象的內(nèi)部細(xì)節(jié),只保留有限的對(duì)外接口實(shí)現(xiàn)對(duì)外聯(lián)系。每個(gè)對(duì)象都有自身唯一的標(biāo)識(shí),通過(guò)這種標(biāo)識(shí),可找到相應(yīng)的對(duì)象。在對(duì)象的整個(gè)生命期中,它的標(biāo)識(shí)都不改變,不同的對(duì)象不能有相同的標(biāo)識(shí)。2.類具有相同屬性和方法的對(duì)象可歸納成類,對(duì)象是類的一個(gè)實(shí)例,而對(duì)象的抽象是類。類具有屬性,它是對(duì)象的狀態(tài)的抽象,用數(shù)據(jù)結(jié)構(gòu)來(lái)描述類的屬性;類具有操作,它是對(duì)象的行為的抽象,用操作名和實(shí)現(xiàn)該操作的方法來(lái)描述。3.1面向?qū)ο蟮幕靖拍?.對(duì)象3.1面向?qū)ο蟮幕靖拍?.繼承類有一定的結(jié)構(gòu),可以派生出子類,子類除了繼承父類的屬性和方法外還可以有自己的屬性和方法。對(duì)象和類之間的層次結(jié)構(gòu)靠繼承關(guān)系維系。繼承是子類自動(dòng)共享父類數(shù)據(jù)結(jié)構(gòu)和方法的機(jī)制,也是面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言不同于其他語(yǔ)言的最重要的特點(diǎn)。在類層次中,將子類只繼承一個(gè)父類的數(shù)據(jù)結(jié)構(gòu)和方法的方式稱為單重繼承;將子類繼承多個(gè)父類的數(shù)據(jù)結(jié)構(gòu)和方法的方式稱為多重繼承。在軟件開發(fā)中,類的繼承使所建立的軟件具有開放性、可擴(kuò)充性,這是信息組織與分類的行之有效的方法,它簡(jiǎn)化了對(duì)象、類的創(chuàng)建工作量,增加了代碼的重用性。同時(shí),通過(guò)類的繼承關(guān)系,使公共的特性能夠共享,提高了軟件的重用性。4.消息對(duì)象之間的聯(lián)系主要是通過(guò)傳遞消息來(lái)實(shí)現(xiàn),消息傳遞是對(duì)象間通信的手段,一個(gè)對(duì)象通過(guò)向另一個(gè)對(duì)象發(fā)送消息來(lái)請(qǐng)求其服務(wù)。一個(gè)消息通常包含接收對(duì)象的標(biāo)識(shí)、發(fā)送給接收對(duì)象的消息名(方法名)和適當(dāng)?shù)膮?shù)。消息只告訴接收對(duì)象需要完成什么操作,但并不指示接收者如何完成操作。消息完全由接收者解釋,并由其獨(dú)立決定采用什么方法完成所需的操作。3.1面向?qū)ο蟮幕靖拍?.繼承3.1面向?qū)ο蟮幕靖拍?.多態(tài)性多態(tài)性是指相同的操作或方法可作用于多種類型的對(duì)象上并獲得不同的結(jié)果。即將不同的對(duì)象收到同一消息時(shí)產(chǎn)生不同的結(jié)果的現(xiàn)象稱為多態(tài)性。多態(tài)性允許每個(gè)對(duì)象以適合自身的方式去響應(yīng)共同的消息,增強(qiáng)了軟件的靈活性和重用性。面向?qū)ο蠹夹g(shù)正是利用對(duì)現(xiàn)實(shí)世界中對(duì)象的抽象和對(duì)象之間的相互關(guān)聯(lián)和相互作用的描述來(lái)模擬現(xiàn)實(shí)世界,并且使其映射到目標(biāo)系統(tǒng)中。3.1面向?qū)ο蟮幕靖拍?.多態(tài)性3.2類和對(duì)象

類是對(duì)象的抽象描述,類似于模板。從定義上來(lái)說(shuō),類是一種復(fù)雜的數(shù)據(jù)結(jié)構(gòu),其中包含數(shù)據(jù)成員和功能成員。在C#中,類必須先定義后使用。1.類的定義類是C#中最基礎(chǔ)的類型。類是一個(gè)數(shù)據(jù)結(jié)構(gòu),將數(shù)據(jù)成員(狀態(tài))和功能成員(行為)組合在一個(gè)單元中,進(jìn)而體現(xiàn)了面向?qū)ο蠹夹g(shù)的封裝性。類的定義格式如下:Attribute類修飾符class類名[:基類和實(shí)現(xiàn)的接口列表]{

類成員定義}其中,類的修飾符如下表所示。修飾符描述none、internal類只能在當(dāng)前項(xiàng)目中訪問(wèn)public類可以在任何地方訪問(wèn)abstract、internalabstract類只能在當(dāng)前項(xiàng)目中訪問(wèn),且不能實(shí)例化,只能繼承publicabstract類可以在任何地方訪問(wèn),且不能實(shí)例化,只能繼承sealed、internalsealed類只能在當(dāng)前項(xiàng)目中訪問(wèn),且只能實(shí)例化,不能繼承publicsealed類可以在任何地方訪問(wèn),且只能實(shí)例化,不能繼承3.2類和對(duì)象類是對(duì)象的抽象描述,類似于模3.2類和對(duì)象下面是一個(gè)名為Point的簡(jiǎn)單類的聲明。publicclassPoint{privateintx,y;//數(shù)據(jù)成員

publicPoint(intx,inty){//功能成員

this.x=x;this.y=y;}}3.2類和對(duì)象下面是一個(gè)名為Point的簡(jiǎn)單類的聲明。3.2類和對(duì)象2.類的成員類的成員分為數(shù)據(jù)成員和功能成員,其中數(shù)據(jù)成員包括:成員常量,代表與類相關(guān)的常數(shù)數(shù)據(jù);字段,類的變量。功能成員包括:方法,即類中的成員函數(shù);屬性,定義了命名的屬性以及讀寫屬性的相關(guān)的行為;索引,允許類的實(shí)例通過(guò)與數(shù)組相同的方法來(lái)索引;操作符,定義了可以用于類的實(shí)例上的表達(dá)式操作;事件,定義了由類產(chǎn)生的事件公告;構(gòu)造函數(shù),對(duì)類的實(shí)例進(jìn)行初始化的操作;析構(gòu)函數(shù),在類的實(shí)例銷毀前執(zhí)行與資源釋放相關(guān)的操作。3.類成員的可訪問(wèn)性類的每個(gè)成員都有關(guān)聯(lián)的可訪問(wèn)性,它控制能夠訪問(wèn)該成員的程序區(qū)域。在C#中,有5種可能的可訪問(wèn)性,如下表所示??稍L問(wèn)性描

述public訪問(wèn)不受限制,定義的成員可以在類的外部訪問(wèn)protected訪問(wèn)僅限于包含類或從包含類派生的類internal訪問(wèn)僅限于當(dāng)前程序集(包)protectedinternal訪問(wèn)僅限于從包含類派生的當(dāng)前程序集(包)或類private訪問(wèn)僅限于包含類3.2類和對(duì)象2.類的成員可訪問(wèn)性描述pu3.2類和對(duì)象4.靜態(tài)成員和非靜態(tài)成員類的成員可以是靜態(tài)成員,也可以是非靜態(tài)成員。在C#中,用關(guān)鍵字static修飾的類成員(包括字段、方法、屬性、事件、操作符或構(gòu)造函數(shù))稱為靜態(tài)成員,它們屬于類。而沒有用關(guān)鍵字static修飾的類成員稱為非靜態(tài)成員,它們屬于對(duì)象。靜態(tài)成員具有如下特征。一個(gè)靜態(tài)字段對(duì)應(yīng)一個(gè)存儲(chǔ)位置,不管其包含類創(chuàng)建了多少個(gè)實(shí)例,總是只有一個(gè)靜態(tài)字段的備份。靜態(tài)成員(包括方法、屬性、事件、操作符或構(gòu)造函數(shù))不會(huì)對(duì)非靜態(tài)成員進(jìn)行操作,也不能使用this。靜態(tài)成員屬于類,因此可以在包含類的實(shí)例之間共享它們。靜態(tài)成員一般通過(guò)類來(lái)訪問(wèn),例如Console.ReadLine(

),其中ReadLine(

)就是類Console中的靜態(tài)方法。對(duì)于非靜態(tài)字段,在包含類的每個(gè)實(shí)例中都包括一個(gè)它的獨(dú)立備份,同時(shí)在非靜態(tài)成員中可以使用this,也可以對(duì)非靜態(tài)成員進(jìn)行操作。非靜態(tài)成員通過(guò)包含類的實(shí)例來(lái)訪問(wèn)。3.2類和對(duì)象4.靜態(tài)成員和非靜態(tài)成員3.2類和對(duì)象5.對(duì)象對(duì)象是類的實(shí)例。與C++不同,在C#中,類是一種引用類型,因此在C#中不能直接用類來(lái)定義對(duì)象,它定義的只是一個(gè)對(duì)象引用變量。一般可以使用new運(yùn)算符動(dòng)態(tài)創(chuàng)建一個(gè)對(duì)象,再將其賦值給一個(gè)對(duì)象引用變量。例如:Pointp1=newPoint(0,0);//指向一個(gè)動(dòng)態(tài)創(chuàng)建的Point對(duì)象Pointp2=p1;//p1和p2指向同一個(gè)Point對(duì)象Pointp3;//不指向任何對(duì)象當(dāng)不再使用對(duì)象時(shí),該對(duì)象所占的內(nèi)存將被自動(dòng)回收。在C#中,沒有必要也不可能顯式地釋放對(duì)象。而是通過(guò)系統(tǒng)中的垃圾回收器來(lái)實(shí)現(xiàn)對(duì)無(wú)用對(duì)象的回收操作。6.構(gòu)造函數(shù)與析構(gòu)函數(shù)

C#既支持實(shí)例構(gòu)造函數(shù),也支持靜態(tài)構(gòu)造函數(shù)。實(shí)例構(gòu)造函數(shù)用來(lái)初始化類實(shí)例中的數(shù)據(jù)成員。靜態(tài)構(gòu)造函數(shù)用來(lái)在類首次加載時(shí)初始化類本身的數(shù)據(jù)成員,即靜態(tài)字段。構(gòu)造函數(shù)的名稱與類名相同,沒有返回類型。若構(gòu)造函數(shù)的聲明中包含static修飾符,則它聲明了一個(gè)靜態(tài)構(gòu)造函數(shù),否則聲明的是實(shí)例構(gòu)造函數(shù)。靜態(tài)構(gòu)造函數(shù)不需要訪問(wèn)修飾符,同時(shí)也不帶任何參數(shù);實(shí)例構(gòu)造函數(shù)可以帶參數(shù)表,可以加訪問(wèn)修飾符進(jìn)行修飾,不能被繼承。如果一個(gè)類沒有聲明任何實(shí)例構(gòu)造函數(shù),則會(huì)自動(dòng)為它提供一個(gè)默認(rèn)的空的實(shí)例構(gòu)造函數(shù),一般其參數(shù)列表為空,函數(shù)體也為空。3.2類和對(duì)象5.對(duì)象3.2類和對(duì)象

由于實(shí)例構(gòu)造函數(shù)可以帶參數(shù),因此實(shí)例構(gòu)造函數(shù)可以重載,并且可以通過(guò)參數(shù)列表(參數(shù)的個(gè)數(shù)、類型和順序)來(lái)區(qū)分不同的實(shí)例構(gòu)造函數(shù)。析構(gòu)函數(shù)是用于實(shí)現(xiàn)析構(gòu)類實(shí)例所需操作的成員。析構(gòu)函數(shù)不能帶參數(shù),不能具有可訪問(wèn)性修飾符,也不能被顯式地調(diào)用。當(dāng)沒有任何代碼要使用一個(gè)實(shí)例時(shí),系統(tǒng)中的垃圾回收器會(huì)自動(dòng)調(diào)用該實(shí)例的析構(gòu)函數(shù)對(duì)其進(jìn)行析構(gòu),如代碼實(shí)例所示。usingSystem;namespaceex_3_1{classProgram{privateintdata;//非靜態(tài)數(shù)據(jù)成員(字段)

staticprivateintstaticdata;//靜態(tài)數(shù)據(jù)成員

publicProgram(

)//無(wú)參數(shù)實(shí)例構(gòu)造函數(shù)

{Console.WriteLine("無(wú)參數(shù)構(gòu)造函數(shù)");data=0;}publicProgram(intvalue)//帶參數(shù)實(shí)例構(gòu)造函數(shù)

{Console.WriteLine("帶參數(shù)構(gòu)造函數(shù)");data=value;}staticProgram(

)//靜態(tài)構(gòu)造函數(shù)

{Console.WriteLine("靜態(tài)構(gòu)造函數(shù)");staticdata=100;}

~Program(

)//析構(gòu)函數(shù)

{Console.WriteLine("析構(gòu)函數(shù)");}publicvoidPrint(

)//打印方法

{Console.WriteLine("Staticdatais{0},Datais{1}",staticdata,data);}staticvoidMain(string[]args){Programp1;//沒有創(chuàng)建對(duì)象

Programp2=newProgram(

);//創(chuàng)建一個(gè)對(duì)象

Programp3=newProgram(50);//創(chuàng)建一個(gè)對(duì)象

p1=p3;p1.Print(

);p2.Print(

);p3.Print(

);}}}3.2類和對(duì)象由于實(shí)例構(gòu)造函數(shù)可以帶參數(shù),3.3字段

字段,即類的變量,類中的數(shù)據(jù)成員,用來(lái)存儲(chǔ)類所需的數(shù)據(jù)信息。它可以聲明為靜態(tài)的,也可以聲明為只讀的(readonly)。當(dāng)字段被聲明為只讀時(shí)與聲明為const的效果是一樣的,區(qū)別在于只讀型表達(dá)式在程序運(yùn)行時(shí)形成,而const型表達(dá)式的值在編譯時(shí)形成。只讀型字段可以通過(guò)構(gòu)造函數(shù)賦值,但實(shí)例創(chuàng)建后則不能再對(duì)其進(jìn)行賦值。字段聲明的格式如下:修飾符字段類型字段名列表;其中修飾符可以是public、protected、internal、private、static和readonly;字段類型可以是基本類型、用戶自定義類型和其他類。例如:classCalendarDate{publicreadonlyintmonth;//只讀字段,實(shí)例創(chuàng)建后不能對(duì)其賦值

publicintday;publicstaticintyear=2019;//靜態(tài)字段,屬于類的成員}

雖然字段是一種類變量,但是C#為每個(gè)未初始化的變量都確認(rèn)一個(gè)默認(rèn)值,因此字段聲明后便可以使用。這在一定程度上保證了程序的安全性。如下代碼實(shí)例所示為字段使用的程序?qū)嵗?.3字段字段,即類的變量,類中的數(shù)據(jù)成3.3字段usingSystem;namespaceex_3_2{classProgram{publicreadonlyintmonth;publicintday;publicstaticintyear=2019;publicProgram(

)//無(wú)參數(shù)的構(gòu)造函數(shù)

{}publicProgram(intd,intm,inty)//構(gòu)造函數(shù)中可以對(duì)只讀型字段賦值

{day=d;month=m;year=y;}publicvoidPrint(

){Console.WriteLine("Yearis{0},Monthis{1},Dayis{2}",year,month,day);}staticvoidMain(string[]args){Programp1=newProgram(10,10,2019);Programp2=newProgram(

);//字段具有默認(rèn)值

p1.Print(

);p2.Print(

);p1.day=11;//p1.month=11;//錯(cuò)誤,只讀型字段不能修改

p1.Print(

);}}}3.3字段usingSystem;3.4方法

方法是一種用于實(shí)現(xiàn)可以由對(duì)象或類執(zhí)行的計(jì)算或操作的功能成員。與C++中的函數(shù)成員類似,方法可以是靜態(tài)也可以是非靜態(tài)。靜態(tài)方法只能通過(guò)類來(lái)訪問(wèn),非靜態(tài)方法(即實(shí)例方法)則要通過(guò)類的實(shí)例訪問(wèn)。方法有一個(gè)參數(shù)表(可能為空),表示傳遞給方法的值或者引用;方法還有返回類型,用于指定由該方法計(jì)算和返回的值的類型。如果方法不返回值,則它的返回類型為void。方法的聲明格式如下: 修飾符返回類型方法名稱(參數(shù)列表)

{

方法體

}

其中,方法的名稱、參數(shù)個(gè)數(shù)、參數(shù)順序、每個(gè)參數(shù)的修飾符和類型一起組成方法的簽名。在聲明方法的類中,該方法的簽名必須是唯一的。正因?yàn)榉椒梢詭?shù),所以類中的方法可以重載,重載方法的簽名不同,主要是參數(shù)個(gè)數(shù)、參數(shù)類型和參數(shù)順序不同。3.4方法方法是一種用于實(shí)現(xiàn)可以由對(duì)3.4方法

在C#中,方法中的參數(shù)用于將值或者引用變量傳遞給方法體。當(dāng)方法被調(diào)用時(shí),方法的參數(shù)從指定的自變量得到它們實(shí)際的值。C#中有4種參數(shù):值參數(shù)、引用參數(shù)、輸出參數(shù)和參量參數(shù)。值參數(shù):用于輸入?yún)?shù)的傳遞。值參數(shù)相當(dāng)于一個(gè)局部變量,它的初始值是從實(shí)參獲得的。對(duì)值參數(shù)的修改不會(huì)影響其對(duì)應(yīng)的實(shí)參。引用參數(shù):用于輸入和輸出數(shù)據(jù)的傳遞。引用參數(shù)對(duì)應(yīng)的實(shí)參必須是一個(gè)變量,并且在方法執(zhí)行期間,引用參數(shù)和其實(shí)參指向同一個(gè)存儲(chǔ)空間,因此,引用參數(shù)值的變化將直接影響其實(shí)參。引用參數(shù)用ref修飾符聲明。輸出參數(shù):用于輸出數(shù)據(jù)的傳遞。輸出參數(shù)類似于引用參數(shù),不同之處在于實(shí)參有無(wú)初始值無(wú)關(guān)緊要。輸出參數(shù)用out修飾符聲明。參量參數(shù):可以把一維數(shù)組或不規(guī)則數(shù)組傳遞給方法。在方法聲明的參數(shù)列表中,參量參數(shù)必須以params開始,例如:publicintsum(paramint[]intParams){方法體}。在帶參量參數(shù)的方法調(diào)用中,既可以傳遞數(shù)組類型的單個(gè)實(shí)參,也可以傳遞充當(dāng)數(shù)組元素的若干實(shí)參。對(duì)于后一種的情形,數(shù)組實(shí)例將自動(dòng)被創(chuàng)建,并且通過(guò)給定的實(shí)參初始化。3.4方法在C#中,方法中的參數(shù)用于3.4方法usingSystem;namespaceex_3_3{classFunc_Ex{staticprivateintobject_num=0;//靜態(tài)字段

publicintx,y,xy;privateintm_sum;publicFunc_Ex(inta,intb)//構(gòu)造函數(shù)

{x=a;y=b;object_num++;//統(tǒng)計(jì)對(duì)象實(shí)例個(gè)數(shù)

}publicvoidswap(inta,intb)//值參數(shù)

{inttemp;temp=a;a=b;b=temp;}publicvoidswap(refinta,refintb,outints)//引用參數(shù),輸出參數(shù)

{inttemp;temp=a;a=b;b=temp;

s=a+b;}publicvoidsum(paramsint[]intparams)//參量參數(shù)

{m_sum=0;foreach(intvinintparams)m_sum+=v;}publicvoidprint(

)//實(shí)例方法

{Console.WriteLine("x={0},y={1},xy={2},sum={3}",x,y,xy,m_sum);}staticpublicvoidprintObjectNum(

)//靜態(tài)方法

{Console.WriteLine("已創(chuàng)建的對(duì)象個(gè)數(shù)為{0}",object_num);}staticvoidMain(string[]args){Func_Exf1=newFunc_Ex(10,20);Func_Ex.printObjectNum(

);f1.print(

);//靜態(tài)方法調(diào)用

f1.swap(f1.x,f1.y);/*值參數(shù)的方法調(diào)用*/f1.print(

);f1.swap(reff1.x,reff1.y,outf1.xy);/*引用和輸出參數(shù)的方法調(diào)用*/f1.print(

);

Func_Exf2=newFunc_Ex(100,220);Func_Ex.printObjectNum(

);/*靜態(tài)方法調(diào)用*/f2.print(

);f2.sum(10,20,30,45);/*參量參數(shù)的方法調(diào)用*/f2.print(

);int[]a={1,3,5,7,9,11,23};f2.sum(a);/*參量參數(shù)的方法調(diào)用*/f2.print(

);

}}}3.4方法usingSystem;public3.5屬性與索引3.5.1屬性屬性是對(duì)對(duì)象或類的字段進(jìn)行特定訪問(wèn)的成員,是字段的自然擴(kuò)展,并且訪問(wèn)屬性和字段的語(yǔ)法相同。在C#中屬性與字段完全相同,屬性不表示存儲(chǔ)位置。而且屬性有訪問(wèn)器,通過(guò)這些訪問(wèn)器可以實(shí)現(xiàn)對(duì)相關(guān)字段值(或計(jì)算值)的訪問(wèn)。在C#中,屬性的聲明格式如下:修飾符類型屬性名{get{

執(zhí)行代碼;

return表達(dá)式;

}set{

執(zhí)行代碼

}}get訪問(wèn)器和set訪問(wèn)器的功能如下。get訪問(wèn)器相當(dāng)于一個(gè)具有屬性類型返回值的無(wú)參數(shù)方法。當(dāng)在表達(dá)式中引用屬性時(shí),會(huì)調(diào)用該屬性的get訪問(wèn)器來(lái)計(jì)算該屬性的值。set訪問(wèn)器相當(dāng)于一個(gè)具有單個(gè)名為value的參數(shù)和無(wú)返回類型的方法。當(dāng)屬性作為賦值運(yùn)算的左值表達(dá)式或者作為++或運(yùn)算符的操作數(shù)被引用時(shí),就會(huì)調(diào)用set訪問(wèn)器來(lái)修改相應(yīng)字段中的值。3.5屬性與索引3.5.1屬性3.5屬性與索引3.5.1屬性兩種訪問(wèn)器都包含的屬性稱為讀寫屬性,只具有g(shù)et訪問(wèn)器的屬性稱為只讀屬性,只具有set訪問(wèn)器的屬性稱為只寫屬性。與字段和方法類似,屬性可以被定義為實(shí)例屬性和靜態(tài)屬性。靜態(tài)屬性的聲明中具有static修飾符,而實(shí)例屬性則沒有,靜態(tài)屬性只能訪問(wèn)靜態(tài)成員。屬性的訪問(wèn)器可以是虛擬的。當(dāng)屬性聲明中包含virtual、abstract、override修飾符時(shí),它們將運(yùn)用到屬性訪問(wèn)器。但是,與字段或方法不完全相同,屬性聲明時(shí)需要注意如下幾點(diǎn)屬性不能聲明為const,也不能在一個(gè)表達(dá)式聲明多個(gè)屬性。不能通過(guò)set訪問(wèn)器對(duì)屬性進(jìn)行初始化。屬性不屬于變量,不能將屬性作為引用參數(shù)或輸出參數(shù)傳遞。屬性必須有返回類型,并且不能為void型。在屬性聲明中,除了get和set訪問(wèn)器外,不能進(jìn)行其他任何操作。3.5屬性與索引3.5.1屬性3.5屬性與索引3.5.2索引索引是這樣一個(gè)成員,它使對(duì)象能夠用與數(shù)組相同的方式進(jìn)行索引。索引的聲明與屬性很相似,不同之處在于成員的名字是this,后面的參數(shù)列表在定界符“[]”之間。參數(shù)在索引的訪問(wèn)器中是可用的。索引的聲明形式如下:修飾符類型this[類型index]{get{

執(zhí)行代碼;//主要是對(duì)index值指定的相應(yīng)數(shù)組字段的某個(gè)元素進(jìn)行訪問(wèn)

return表達(dá)式;

}set{

執(zhí)行代碼;//主要是對(duì)index值指定的相應(yīng)數(shù)組字段的某個(gè)元素進(jìn)行訪問(wèn)

}}

如果包含get和set訪問(wèn)器,則該索引是讀寫索引;如果只包含get訪問(wèn)器則是只讀索引;而只包含set訪問(wèn)器則是只寫索引。注意:索引主要是用來(lái)通過(guò)數(shù)組下標(biāo)的方式操作對(duì)象實(shí)例中的某個(gè)數(shù)組型字段成員的數(shù)組元素,而不是對(duì)象實(shí)例數(shù)組。3.5屬性與索引3.5.2索引3.5屬性與索引usingSystem;namespaceEx_3_4{classNameList{privatestring[]namelist;//名稱數(shù)組

privatereadonlyintMaxLength;//數(shù)組最大長(zhǎng)度

privateintnamecount=0;//數(shù)組當(dāng)前長(zhǎng)度

staticprivateintnamelistcount=0;//實(shí)例個(gè)數(shù)

privatestringnamelisttile;//名稱標(biāo)題字段

publicNameList(intmaxlength)//構(gòu)造函數(shù)

{MaxLength=maxlength;namelist=newstring[MaxLength];namecount=0;namelistcount++;}staticpublicintNameListCount//靜態(tài)屬性

{get{returnnamelistcount;}}publicstringNameListTile//讀寫屬性

{get{returnnamelisttile;}set{namelisttile=value;}}publicintMAXLength//只讀屬性

{get{returnMaxLength;}}publicintCount//只讀屬性

{get{returnnamecount;}}publicstringthis[intindex]//讀寫索引

{get{if((index>=0)&&(index<namecount))returnnamelist[index];elsereturn"";}set{if((index>=0)&&(index<namecount))namelist[index]=value;}}publicvoidAddName(stringv)//方法

{if(namecount<MaxLength)namelist[namecount++]=v;}publicvoidPrintNamelist(

)//方法

{Console.WriteLine("NameListTileis{0}",namelisttile);for(inti=0;i<namecount;i++)Console.WriteLine("\tNamelist[{0}]is{1}",i,namelist[i]);}

3.5屬性與索引usingSystem;publi3.5屬性與索引staticvoidMain(string[]args)//測(cè)試代碼

{NameListnl1=newNameList(20);//創(chuàng)建兩個(gè)對(duì)象

NameListnl2=newNameList(10);nl1.NameListTile="NameBook1";for(inti=0;i<10;i++)nl1.AddName("Name"+i.ToString(

));

nl2.NameListTile="NameBook2";for(inti=0;i<5;i++)nl2.AddName("Book"+i.ToString(

));nl2[0]="ITBook_0";//通過(guò)索引設(shè)置實(shí)例的值

nl2[1]="ITBook_1";nl1.PrintNamelist(

);Console.WriteLine("NameList2Titleis{0}",nl2.NameListTile);for(intk=0;k<nl2.Count-1;k++)Console.WriteLine("\tNameList2[{0}]is{1}",k,nl2[k]);//通過(guò)索引讀取實(shí)例的值

}}}3.5屬性與索引staticvoidMain(str3.6委托與事件3.6.1委托委托是事件的基礎(chǔ)。它是一種變量類型,類似于C++中的函數(shù)指針,可以間接地實(shí)現(xiàn)與命名方法或匿名方法的關(guān)聯(lián),提供在程序運(yùn)行期間對(duì)不同方法(或函數(shù))進(jìn)行選擇的能力,即后聯(lián)編,但是,委托是類型安全和可靠的。與抽象方法類似,委托在聲明中指定了方法的返回類型和形式參數(shù)類型,但沒有指定具體的實(shí)現(xiàn)過(guò)程,其聲明格式如下:[修飾符]delegate類型委托名([參數(shù)列表]);其中修飾符和參數(shù)列表都是可選的。委托定義了方法的返回類型和參數(shù)列表,每一個(gè)使用委托的方法都必須與委托有著相同的簽名。定義了委托之后,便可以實(shí)例化委托,并在此基礎(chǔ)上實(shí)現(xiàn)與指定方法的關(guān)聯(lián),進(jìn)而可以通過(guò)委托實(shí)例調(diào)用相關(guān)聯(lián)的方法。委托方法的使用如代碼實(shí)例3.5所示。該實(shí)例實(shí)現(xiàn)了一個(gè)雇員類Employee,并在其中實(shí)現(xiàn)了按年齡比較大小和按薪資比較大小兩種比較方法,以此為基礎(chǔ)在測(cè)試類Test中利用委托實(shí)例做排序函數(shù)參數(shù),進(jìn)而實(shí)現(xiàn)了分別按照年齡和薪資的排序。3.6委托與事件3.6.1委托3.6委托與事件3.6.1委托usingSystem;namespaceEx_3_5{delegateboolCompareOp(objecto1,objecto2);//聲明委托

classEmployee{privateintm_age;privatedoublem_salary;privatestringm_name;publicEmployee(stringname,intage,doublesalary){m_name=name;m_age=age;m_salary=salary;}publicvoidPrint(

){Console.WriteLine("Nameis{0},ageis{1},salaryis{2}",m_name,m_age,m_salary);}

3.6委托與事件3.6.1委托3.6委托與事件3.6.1委托staticpublicboolAgeIsGreater(objecte1,objecte2){Employeeemp1=(Employee)e1;Employeeemp2=(Employee)e2;return(emp1.m_age>emp2.m_age)?true:false;}staticpublicboolSalaryIsGreater(objecte1,objecte2){Employeeemp1=(Employee)e1;Employeeemp2=(Employee)e2;return(emp1.m_salary>emp2.m_salary)?true:false;}}classTest{staticpublicvoidSort(object[]sortArray,CompareOpgtMethod)//使用委托做函數(shù)參數(shù)

{for(inti=0;i<sortArray.Length;i++){for(intj=i+1;j<sortArray.Length;j++){if(gtMethod(sortArray[j],sortArray[i])){objecttemp=sortArray[i];sortArray[i]=sortArray[j];sortArray[j]=temp;}}}}}3.6委托與事件3.6.1委托3.6委托與事件3.6.1委托staticvoidMain(string[]args){Employee[]employees={newEmployee("Wang",20,1000),newEmployee("Li",23,2019),newEmployee("Xu",34,2500),newEmployee("Liu",56,3000),newEmployee("Zhang",45,2300),newEmployee("Yuan",67,5000)};CompareOpCompareByAge=newCompareOp(Employee.AgeIsGreater);//定義委托實(shí)例

CompareOpCompareBySalary=newCompareOp(Employee.SalaryIsGreater);//定義委托實(shí)例

Console.WriteLine("Sortedbyage:");Sort(employees,CompareByAge);//委托實(shí)例作實(shí)參

for(inti=0;i<employees.Length;i++)employees[i].Print(

);Console.WriteLine("Sortedbysalary:");Sort(employees,CompareBySalary);//委托實(shí)例作實(shí)參

for(inti=0;i<employees.Length;i++)employees[i].Print(

);}}3.6委托與事件3.6.1委托staticv3.6委托與事件3.6.2事件

事件是使對(duì)象或類能夠提供通知的成員。如果將某個(gè)為用戶提供服務(wù)的類稱為服務(wù)類,使用服務(wù)的類稱為客戶類,則事件提供了一種在客戶類中擴(kuò)展服務(wù)類的某個(gè)功能的機(jī)制,即在客戶類中可以定義事件響應(yīng)函數(shù)。例如,在Windows程序中,窗口是一個(gè)對(duì)象,當(dāng)用戶在其中單擊按鈕、按下按鍵、最大化或最小化窗口時(shí)都會(huì)激發(fā)響應(yīng)事件,并且用戶可以為該響應(yīng)事件添加執(zhí)行代碼。在C#中,事件機(jī)制的實(shí)現(xiàn)主要包括聲明事件、激活事件、聲明事件響應(yīng)函數(shù)、訂閱事件等步驟,其中聲明事件、激活事件在提供事件通知的服務(wù)類中實(shí)現(xiàn),而聲明事件響應(yīng)函數(shù)和訂閱事件則在使用服務(wù)類的客戶類中實(shí)現(xiàn)。1.聲明事件事件的聲明通過(guò)委托來(lái)實(shí)現(xiàn),先定義委托,再用委托聲明事件,并且通過(guò)委托將事件響應(yīng)函數(shù)關(guān)聯(lián)到事件中。激發(fā)事件的時(shí)候通過(guò)調(diào)用委托實(shí)現(xiàn)對(duì)事件響應(yīng)函數(shù)的調(diào)用。因此事件可以看成是一種特殊的委托,其聲明格式如下:修飾符event類型事件名;其中類型必須是委托類型。例如:publicdelegatevoidAlarmEventHandle(objectsender,stringmsg);//聲明委托publiceventAlarmEventHandleAlarm;//定義事件事件的聲明與字段的聲明類似,不同之處在于事件聲明包含一個(gè)event關(guān)鍵字,并且事件聲明的類型必須是委托類型。在包含事件聲明的類中,事件可以像委托類型的字段一樣使用。3.6委托與事件3.6.2事件3.6委托與事件3.6.2事件2.激活事件當(dāng)事件激活條件滿足并且事件已經(jīng)與某個(gè)事件響應(yīng)函數(shù)關(guān)聯(lián)時(shí)便可以激活事件,即通過(guò)委托實(shí)例調(diào)用委托函數(shù),如下:if((m_currentTime==m_alarmTime)&&(Alarm!=null))Alarm(this,"定時(shí)時(shí)間到!");//條件滿足時(shí)激活事件3.訂閱事件訂閱事件就是實(shí)現(xiàn)事件與事件響應(yīng)函數(shù)的關(guān)聯(lián),即委托實(shí)例與委托函數(shù)的關(guān)聯(lián)。在C#中通過(guò)“+=”操作符實(shí)現(xiàn)事件與事件響應(yīng)函數(shù)的關(guān)聯(lián),通過(guò)“-=”操作符將事件與已關(guān)聯(lián)的事件響應(yīng)函數(shù)去除關(guān)聯(lián),如下:t1.Alarm+=newAlarmEventHandle(OnAlarm);//事件響應(yīng)函數(shù)與事件關(guān)聯(lián)t1.Alarm-=newAlarmEventHandle(OnAlarm);//去掉事件響應(yīng)函數(shù)與事件的關(guān)聯(lián)如果事件沒有實(shí)現(xiàn)與事件響應(yīng)函數(shù)的關(guān)聯(lián)則其值為null。3.6委托與事件3.6.2事件2.激活事件3.6委托與事件3.6.2事件4.聲明事件響應(yīng)函數(shù)事件響應(yīng)函數(shù)是客戶類在接收到服務(wù)類的事件通知后進(jìn)行響應(yīng)處理的函數(shù),類似于回調(diào)函數(shù)。因此通過(guò)事件響應(yīng)函數(shù)可以在客戶類中擴(kuò)展服務(wù)類的某個(gè)功能。事件響應(yīng)函數(shù)是委托實(shí)例的關(guān)聯(lián)函數(shù),因此其簽名應(yīng)與事件的簽名一致。下面的OnAlarm函數(shù)便是事件Alarm的事件響應(yīng)函數(shù)。staticpublicvoidOnAlarm(objectsender,stringmsg)//聲明事件響應(yīng)函數(shù){Console.WriteLine("Alarmmessageis{0}",msg);}事件機(jī)制的使用如代碼實(shí)例3.6所示。該實(shí)例中定義了一個(gè)定時(shí)器類Timer,當(dāng)定時(shí)事件與當(dāng)前時(shí)間一致時(shí)將通知客戶程序,并通過(guò)與Alarm事件關(guān)聯(lián)的事件響應(yīng)函數(shù)進(jìn)行處理。而在測(cè)試類Test中定義了Timer類的對(duì)象,并將已定義好的事件響應(yīng)函數(shù)與事件Alarm實(shí)現(xiàn)關(guān)聯(lián),同時(shí)也測(cè)試了去掉關(guān)聯(lián)后的運(yùn)行效果。3.6委托與事件3.6.2事件4.聲明事件響3.6委托與事件3.6.2事件usingSystem;namespaceEx_3_6{publicdelegatevoidAlarmEventHandle(objectsender,stringmsg);//聲明委托

classTimer{privateDateTimem_currentTime,m_alarmTime;//定義字段

publiceventAlarmEventHandleAlarm;//定義事件

publicTimer(DateTimect,DateTimeat){m_currentTime=ct;m_alarmTime=at;}publicDateTimeCurrentTime{get{returnm_currentTime;}set{m_currentTime=value;if((m_currentTime==m_alarmTime)&&(Alarm!=null))Alarm(this,"定時(shí)時(shí)間到!");//條件滿足時(shí)激活事件

}}

3.6委托與事件3.6.2事件usingS3.6委托與事件3.6.2事件publicDateTimeAlarmTime{get{returnm_alarmTime;}set{m_alarmTime=value;if((m_currentTime==m_alarmTime)&&(Alarm!=null))Alarm(this,"定時(shí)時(shí)間到!");//條件滿足時(shí)激活事件

}}}classTest{staticpublicvoidOnAlarm(objectsender,stringmsg)//聲明事件響應(yīng)函數(shù)

{Console.WriteLine("Alarmmessageis{0}",msg);}staticvoidMain(string[]args){DateTimealarmtime=DateTime.Parse("6/2/201921:30:00");Timert1=newTimer(DateTime.Now,alarmtime);t1.Alarm+=newAlarmEventHandle(OnAlarm);//事件響應(yīng)函數(shù)與事件關(guān)聯(lián)

t1.CurrentTime=alarmtime;//將激活事件響應(yīng)函數(shù)

t1.Alarm-=newAlarmEventHandle(OnAlarm);//去掉事件響應(yīng)函數(shù)與事件的關(guān)聯(lián)

t1.CurrentTime=alarmtime;//事件響應(yīng)函數(shù)為空,不作處理

}}}3.6委托與事件3.6.2事件public3.7繼承與多態(tài)

3.7.1繼承現(xiàn)實(shí)世界中實(shí)體之間不是相互孤立的,它們往往具有共同的特征,也有著內(nèi)在的差別。人們可以采用層次結(jié)構(gòu)來(lái)抽象描述這些實(shí)體之間的相同之處和不同之處,如圖3.3所示的交通工具的分類。為了用程序語(yǔ)言對(duì)現(xiàn)實(shí)世界中的層次結(jié)構(gòu)進(jìn)行模型化,面向?qū)ο蠹夹g(shù)引入了繼承的概念,一個(gè)類可以從另一個(gè)類派生出來(lái),派生類繼承了基類的相應(yīng)特性,同時(shí),派生類也可以作為其他類的基類,進(jìn)而實(shí)現(xiàn)類間的層次繼承關(guān)系。因此,繼承是一種共性的抽象機(jī)制。圖3.3

交通工具的分類3.7繼承與多態(tài)3.7.1繼承圖3.3交3.7繼承與多態(tài)

3.7.1繼承1.繼承的定義

C++中,派生類可以繼承一個(gè)基類或多個(gè)基類的特性,而在C#中,派生類只能從一個(gè)類中繼承。派生類的聲明格式如下:[修飾符]class派生類名[:基類名]{

派生類成員

}

派生類能從它的直接基類中繼承的成員包括方法、字段、屬性、事件、索引,即除了構(gòu)造函數(shù)和析構(gòu)函數(shù),派生類隱式地繼承了直接基類的所有成員。在C#中,關(guān)于繼承需要注意以下幾個(gè)重要規(guī)則。繼承是可傳遞的。如果C從B中派生,B又從A中派生,那么C不僅繼承了B中聲明的成員,而且繼承了A中的成員。派生類應(yīng)當(dāng)是對(duì)基類的擴(kuò)展。派生類可以添加新的成員,但不能除去已經(jīng)繼承的成員的聲明。構(gòu)造函數(shù)和析構(gòu)函數(shù)不能被繼承。除此之外的其他成員,不論對(duì)它們聲明了怎樣的訪問(wèn)方式,都能被繼承?;愔谐蓡T的訪問(wèn)方式只能決定派生類能否訪問(wèn)它們。派生類如果聲明了與繼承而來(lái)的成員同名的新成員,就可以覆蓋已繼承的成員。但這并不意味著派生類刪除了這些成員,只是不能再訪問(wèn)這些成員。類可以聲明虛方法、虛屬性,以及虛索引,它的派生類能夠重載這些成員,從而實(shí)現(xiàn)類的多態(tài)性。

3.7繼承與多態(tài)3.7.1繼承3.7繼承與多態(tài)

3.7.1繼承2.覆蓋在派生類的成員聲明中,可以聲明與繼承而來(lái)的成員同名的成員,并且使用相同的簽名。這時(shí)我們稱派生類的成員覆蓋了基類的成員。在C#中,要實(shí)現(xiàn)覆蓋的成員,一般在基類中將其聲明為virtual或override,而派生類中覆蓋成員聲明為override。即基類中的virtual成員在派生類中可以覆蓋,基類中的覆蓋成員在派生類中可以進(jìn)一步聲明為覆蓋成員。其中用virtual修飾的成員稱為虛成員,而用override修飾的成員稱為覆蓋成員。如下所示:classShape{……virtualpublicvoidPrint(

)//虛方法

{Console.WriteLine("Shapeis{0}",name);}}classLineClass:Shape{……publicoverridevoidPrint(

)//覆蓋方法

{base.Print(

);Console.WriteLine("\tShapetypeisLine,Lengthis{0}",Length);}}

如果基類中的成員在派生類中被覆蓋了,則在派生類中直接用該成員名訪問(wèn)的將是派生類中聲明的成員。為了在派生類中可以繼續(xù)訪問(wèn)基類中的相應(yīng)成員,在C#中引入了base關(guān)鍵字,通過(guò)該關(guān)鍵字可以訪問(wèn)基類中的成員。因此,可以將base看成是一個(gè)指向派生類直接基類的引用,而this則是指向?qū)ο髮?shí)例本身的引用。3.7繼承與多態(tài)3.7.1繼承3.7繼承與多態(tài)

3.7.1繼承3.object類為了提高程序員的編程效率,各種編程環(huán)境(工具)都提供了許多重用度高的類庫(kù),以方便程序員直接使用。同樣,在.NET中也提供了相應(yīng)的類庫(kù)。其中Object是該類庫(kù)中最基本的類,它屬于System命名空間,通常也寫成System.Object。在C#中,所有的類都直接或間接派生于Object類。在聲明類時(shí),如果沒有明確指明基類,則編譯器會(huì)自動(dòng)將Object類指定為其基類。因此,Object類是C#所有類的根,每個(gè)類都將從Object類繼承類成員。表3.3列出了Object類的常用方法。方法訪問(wèn)修飾符作用stringToString(

)publicvirtual返回對(duì)象的字符串表示intGetHashTable(

)publicvirtual在實(shí)現(xiàn)字典(散列表)時(shí)使用boolEquals(objectobj)publicvirtual對(duì)當(dāng)前對(duì)象與obj進(jìn)行相等比較boolEquals(objectobjA,objectobjB)publicstatic在objA和objB之間進(jìn)行相等比較boolReferenceEquals(objectobjA,objectobjB)publicstatic比較objA和objB是否引用的是同一個(gè)對(duì)象TypeGetType(

)public返回對(duì)象類型的詳細(xì)信息objectMemberwiseClone(

)protected進(jìn)行對(duì)象的淺層復(fù)制voidFinalize(

)protectedvirtual該方法是析構(gòu)函數(shù)的.NET版本3.7繼承與多態(tài)3.7.1繼承方法訪問(wèn)3.7繼承與多態(tài)

3.7.2抽象類與密封類1.抽象類為了滿足分層次抽象的需要,在許多面向?qū)ο蟮某绦蛟O(shè)計(jì)語(yǔ)言中都引入了抽象類的概念。抽象類是基類的一種特殊形式,它除了擁有普通的類成員之外,還擁有抽象類成員。在C#中,抽象類成員是指那些只有聲明沒有實(shí)現(xiàn)的方法、屬性或索引,并且使用了abstract修飾符。因此,抽象類不能實(shí)例化,它一般出現(xiàn)在類層次結(jié)構(gòu)中的中間層或根節(jié)點(diǎn)上,不能出現(xiàn)在葉節(jié)點(diǎn)中。在C#中,包含一個(gè)或多個(gè)抽象成員的類本身也必須聲明為abstract,但是抽象類可以包含非抽象的成員。從抽象類派生的類必須對(duì)基類中包含的所有抽象成員進(jìn)行實(shí)現(xiàn),否則它也是抽象類。抽象成員為隱式的虛成員,因此在抽象類的派生類中實(shí)現(xiàn)抽象成員的方法與覆蓋一個(gè)虛方法類似。如下代碼定義了一個(gè)抽象類Shape,其中包含抽象方法和虛方法。abstractclassShape//抽象類{privateintx,y;privatestringname;protectedColorTypeftColor;……abstractpublicvoidDraw(

);//抽象方法

virtualpublicvoidPrint(

)//虛方法

{Console.WriteLine("Shapeis{0}",name);}}3.7繼承與多態(tài)3.7.2抽象類與密封類3.7繼承與多態(tài)

3.7.2抽象類與密封類2.密封類密封類是指那些不能被繼承的類。在C#中,為了提高程序運(yùn)行效率和穩(wěn)定性,對(duì)那些認(rèn)定為不能再繼承的類可以定義為密封類,用修飾符sealed進(jìn)行修飾。當(dāng)一個(gè)類被聲明為密封類后,就不能再用來(lái)派生新的類。因此密封類中不可能存在抽象成員,一般也不存在虛成員。當(dāng)某個(gè)類中的某個(gè)成員認(rèn)定為不能被覆蓋時(shí),也可以將其聲明為密封成員,即用修飾符sealed對(duì)該成員進(jìn)行修飾。包含密封成員的類不一定要聲明為密封類。密封類可以從抽象類派生,也可以使用關(guān)鍵字override覆蓋基類中的虛成員。如下代碼定義了一個(gè)密封類SquareClass,它從基類RectClass派生而來(lái)。sealedclassSquareClass:RectClass//密封類

{publicSquareClass(stringname,intx,inty,intw,intl):base(name,x,y,x+w,y+l){}publicoverridevoidDraw(

){Console.WriteLine("Square{0}isdrawed",Name);}publicoverridevoidPrint(

){Console.WriteLine("Shapeis{0}",Name);Console.WriteLine("\tShapetypeisSquare,Lengthis{0},Areais{1}",Length,GetArea(

));}}

由抽象類和密封類的概念可知,在C#中,修飾符sealed和abstract不能同時(shí)出現(xiàn)在同一個(gè)類或同一個(gè)成員中。3.7繼承與多態(tài)3.7.2抽象類與密封類3.7繼承與多態(tài)

3.7.3接口在C#中,繼承的實(shí)現(xiàn)包括兩種方式:實(shí)現(xiàn)繼承和接口繼承。其中前面所介紹的類繼承方式屬于實(shí)現(xiàn)繼承,它實(shí)現(xiàn)的主要是抽象共享,或派生類對(duì)基類的修改和擴(kuò)展等。接口繼承是一種對(duì)外約定的實(shí)現(xiàn),在接口中定義相關(guān)的對(duì)外約定(包括方法、屬性、索引和事件),即類必須實(shí)現(xiàn)的對(duì)外行為特征,實(shí)現(xiàn)接口的類則實(shí)現(xiàn)了這些約定。這樣客戶程序只要了解類所實(shí)現(xiàn)的接口便可以知道其對(duì)外提供了哪些服務(wù)。在C#中,定義接口的語(yǔ)法規(guī)則如下:

[訪問(wèn)修飾符]interface接口名[:父接口列表] {

接口成員

}

其中接口成員可以是方法、屬性、索引和事件的聲明,但僅僅是聲明,不需要給出實(shí)現(xiàn)體,這與抽象類中的抽象成員類似。父接口列表用于指定接口繼承的父接口,這與類有很大區(qū)別,接口允許多繼承,因此,該列表可以包含無(wú)數(shù)個(gè)接口。如下代碼定義了兩個(gè)接口IRegion和ILine,其中一個(gè)接口定義的是方法,另一個(gè)定義的是屬性。publicinterfaceIRegion{doubleGetArea(

);}publicinterfaceILine{doubleLength{get;}}

接口最終還是要通過(guò)類來(lái)實(shí)現(xiàn),即要求類來(lái)實(shí)現(xiàn)接口中的接口成員,這與派生類要實(shí)現(xiàn)基類中的抽象成員一樣。另外,由于接口中聲明的僅僅是功能約定,即抽象的功能成員,沒有數(shù)據(jù)成員,因此不會(huì)由于多重繼承帶來(lái)二義性問(wèn)題。在C#中,一個(gè)類最多可以有一個(gè)基類,但是可以具有無(wú)限個(gè)接口。3.7繼承與多態(tài)3.7.3接口接3.7繼承與多態(tài)

3.7.4多態(tài)性多態(tài)性是面向?qū)ο蠹夹g(shù)中的一個(gè)重要概念。是指通過(guò)基類引用綁定不同對(duì)象實(shí)例時(shí),同樣的方法可以具有不同的運(yùn)行行為,即對(duì)象運(yùn)行時(shí)刻的類型決定它的行為,而不是它的引用方法編譯時(shí)的類型決定它的行為。在C#中,多態(tài)性的實(shí)現(xiàn)依賴于基類中的虛成員聲明以及派生類中對(duì)虛成員的覆蓋。如下代碼表現(xiàn)了多態(tài)性的實(shí)現(xiàn)。Shapel1=newLineClass("Line1",10,10,20,40);Shaper1=newRectClass("Rect1",20,20,40,50);Shapes1=newSquareClass("Square1",30,30,20,30);l1.Draw(

);l1.Print(

);//依據(jù)Draw和Print在LineClass中的實(shí)現(xiàn)來(lái)執(zhí)行r1.Draw(

);r1.Print(

);//依據(jù)Draw和Print在RectClass中的實(shí)現(xiàn)來(lái)執(zhí)行s1.Draw(

);s1.Print(

);//依據(jù)Draw和Print在SquareClass中的實(shí)現(xiàn)來(lái)執(zhí)行因此,通過(guò)對(duì)象引用調(diào)用的方法的執(zhí)行行為,取決于該對(duì)象引用動(dòng)態(tài)綁定的對(duì)象類型。多態(tài)性在程序運(yùn)行的動(dòng)態(tài)過(guò)程中體現(xiàn),進(jìn)而增加了程序的靈活性和通用型。繼承與多態(tài)的實(shí)現(xiàn)方法如代碼實(shí)例3.7所示,該實(shí)例中定義了抽象類Shape、接口IRegion和ILine、具體類LineClass、RectClass和SquareClass。3.7繼承與多態(tài)3.7.4多態(tài)性3.7繼承與多態(tài)

3.7.4多態(tài)性u(píng)singSystem;namespaceEx_3_7{enumColorType{Red,Green,Blue,Black,White,Yellow};abstractclassShape{privateintx,y;privatestringname;protectedColorTypeftColor;publicShape(

){name="Nonename";x=0;y=0;}publicShape(stringname,intx,inty){=name;this.x=x;this.y=y;}publicColorTypeFtColor{get{returnftColor;}set{ftColor=value;}}

3.7繼承與多態(tài)3.7.4多態(tài)性3.7繼承與多態(tài)

3.7.4多態(tài)性

publicintX{get{returnx;}set{x=value;}}publicintY{get{returny;}set{y=value;}}publicstringName{get{returnname;}}abstractpublicvoidDraw(

);virtualpublicvoidPrint(

){Console.WriteLine("Shapeis{0}",name);}}

3.7繼承與多態(tài)3.7.4多態(tài)性3.7繼承與多態(tài)

3.7.4多態(tài)性publicinterfaceIRegion{doubleGetArea(

);}publicinterfaceILine{doubleLength{get;}}classLineClass:Shape,ILine{privat

溫馨提示

  • 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ù)覽,若沒有圖紙預(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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論