C#面向?qū)ο缶幊躺钊?ppt_第1頁
C#面向?qū)ο缶幊躺钊?ppt_第2頁
C#面向?qū)ο缶幊躺钊?ppt_第3頁
C#面向?qū)ο缶幊躺钊?ppt_第4頁
C#面向?qū)ο缶幊躺钊?ppt_第5頁
已閱讀5頁,還剩44頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第8章 C#面向?qū)ο缶幊躺钊?2,本章要點,8.1 接口 8.2 委托 8.3 事件 8.4 匿名方法,3,8.1 接口,8.1.1 定義接口 8.1.2 接口的實現(xiàn),4,8.1 接口概述,定義接口的語法如下: interface : 在關(guān)鍵字之前,包含一個訪問修飾符,后面緊跟著接口標識符。 :可選部分,用于指定接口繼承的父接口列表,接口允許多繼承,所以從理論上講,一個接口可繼承無數(shù)個接口。 習慣上,接口標識符以大寫字母I開頭。因為,接口可以強制類實現(xiàn)抽象成員,所以接口標識符通常以_able結(jié)尾。,5,8.1.1 定義接口,接口成員 接口繼承列表后面是接口的主體。主體由包圍在大括號中的成員組成

2、。合法的成員如下: 方法 屬性 索引 事件,6,8.1.1 定義接口,注意: 所有的接口成員,都不能包含訪問修飾符。所有成員都隱式地聲明為public,因為它們要從實現(xiàn)接口成員所在的類的外部訪問。在接口中定義的屬性和索引可以有一個抽象的get訪問器,或者一個抽象的set訪問器,或者二者兼有。接口事件與普通事件的聲明方式一樣。,7,8.1.1 定義接口,接口與類 接口的定義很像類或結(jié)構(gòu),它定義了類必須實現(xiàn)的行為類型的特征,相當于一份使用者和實現(xiàn)者之間的合同。接口可以看做只包含抽象函數(shù)的純抽象類。接口最終還是需要由類(或者結(jié)構(gòu))來實現(xiàn),也就要求類要實現(xiàn)接口的抽象函數(shù)成員,這與派生類保證要實現(xiàn)它的基

3、類的抽象函數(shù)一樣。所以接口是通過動態(tài)捆綁函數(shù)調(diào)用純抽象的基類的替代方式。,8,8.1.1 定義接口,即使接口和抽象類在句法和語義上緊密相關(guān),但它們?nèi)杂幸粋€重要的區(qū)別:接口只能包含抽象函數(shù)、抽象的屬性和抽象的索引,而抽象類還可能包含數(shù)據(jù)成員,以及完全實現(xiàn)的函數(shù)、屬性和索引。也正是如此,多重接口才不會像多重繼承那樣存在出現(xiàn)問題的可能性。如此一來,得到一個結(jié)論:一個類最多可以具有一個基類,但可以具有無限個接口。,9,8.1.2 實現(xiàn)接口,接口自身并不包含任何實現(xiàn)代碼,落實這種定義了的“合同”的任務最終落到了類(或結(jié)構(gòu))身上。在C#中,實現(xiàn)接口的方式有兩種: 隱式實現(xiàn) 顯式實現(xiàn) 例子:Explicit

4、Interface.sln,10,8.1.2 實現(xiàn)接口,顯式實現(xiàn)的主要用途是在有多個接口繼承,并且兩個或多個接口使用了同一個名稱聲明成員的場合。要執(zhí)行顯式實現(xiàn),類中需要使用它的完全限定名來實現(xiàn)接口成員,而且在調(diào)用時,必須將類的對象實例轉(zhuǎn)換成單獨的接口類型。也就是說,要把類對象引用強制轉(zhuǎn)換為接口類型來獲取接口的引用。一旦有了接口的引用,我們就可使用點號來調(diào)用接口的方法。 對于隱式實現(xiàn)而言,它和直接由基類產(chǎn)生派生類的方式很相似。 例子:InterfaceExample.sln,11,8.2 委托,8.2.1 引例 8.2.2 定義委托 8.2.3 實例化委托 8.2.4 通過委托調(diào)用方法 8.2.

5、5 多重委托,12,8.2 委托概述,編寫源代碼時,如果我們只知道特定的位置必定發(fā)生某動作,并不知道它的具體實現(xiàn)過程,就可以用委托。 C#的委托是一個類型安全方法引用,可以把引用存儲為函數(shù)的類型。通過委托,程序能夠在運行時刻動態(tài)地調(diào)用不同的方法。委托最重要的作用是建立支持事件的基礎(chǔ)結(jié)構(gòu)。,13,8.2.1 引例,例子: 在一個擁有多種降溫設備(例如:電力空調(diào)、干冰降溫機、氣動降溫機等)的生物實驗室里,因為要完成某項試驗,要求室內(nèi)溫度低于某個臨界溫度值??梢韵胍?,如果實驗室內(nèi)溫度顯著升高或者達到某個較高值,就必須啟用某些降溫設備,來控制室內(nèi)溫度的升高。為此,就要求控制用的軟件系統(tǒng)必須在適當?shù)臅r候

6、啟用適當?shù)慕禍卦O備。,14,8.2.1 引例,為此,設計的控制軟件可以嘗試采用下面這兩種方式來實現(xiàn): 軟件驅(qū)動各個降溫設備經(jīng)常地測量室內(nèi)溫度,根據(jù)溫度變化,各個降溫設備自動啟用。 使用一個監(jiān)視室內(nèi)溫度的模塊,當溫度變化時,就啟動合適的降溫設備。,15,8.2.1 引例,這兩種方式都有其弱點。 在第一種方式中,如果測量的頻率太頻繁,將耗費資源,影響軟件性能,但如果測量次數(shù)太少,又可能會漏掉某些突然變化的情況,導致錯過降溫時機,所以不宜采用; 第二種方式面臨的問題就是:對于不同的降溫設備,要使用不同的控制方法,對于編程而言,會導致過于復雜,并難以維護。,16,8.2.1 引例,要解決這個問題,推薦

7、使用委托。 委托與抽象方法一樣,它指定了方法的返回類型和形式參數(shù)類型,但沒有指定具體的實現(xiàn)過程,只要這些方法與委托的簽名(返回類型及形式參數(shù))相同。同一個委托在運行期間可以表示不同的方法實現(xiàn)過程。只是在運行時,為委托賦一個適當?shù)姆椒?,當調(diào)用此委托時,它將執(zhí)行此方法實際所封裝的代碼。,17,8.2.2 定義委托,委托定義了方法的返回類型和參數(shù)類型,也創(chuàng)建了一種新類型,每個使用委托的方法都必須提供。委托也是一個類,它派生于基類System.Delegate。和其他類一樣,必須首先定義委托,然后才能實例化。下面給出了委托定義的語法: modifiers delegate (parameter lis

8、t); 其中modifiers(訪問修飾符)和parameter(參數(shù))是可選項。 下面是聲明委托的例子: public delegate double Calculation (double val1, double val2),18,8.2.3 實例化委托,定義了委托之后,必須要實例化委托,還需要委托的方法處理程序,這個方法實現(xiàn)具體的功能,其參數(shù)列表必須相同,并且必須返回同樣的類型。然后再將這個方法賦給委托對象。,19,8.2.3 實例化委托,public delegate double Calculation(double var1, double var2); public class

9、 Example / 實例化委托. Calculation CalcInstance; public double MyMethod(double var1, double var2) . / 接通委托和方法. CalcInstance = new Calculation(MyMethod); ,20,8.2.4 通過委托調(diào)用方法,通過上述工作,我們就可以使用委托了。使用委托就好像它就是委托的方法本身一樣,和直接使用方法的格式相同。我們可以通過下面的語句,來調(diào)用委托: double result=CalcInstance (2455.589d,448247.45d) ; 上面的語句和下面的語句

10、等價: double result=MyMethod (2455.589d,448247.45d) ;,21,補充:聲明委托類型,委托是類型,就好像類是類型一樣。與類一樣,委托類型必須在被用來創(chuàng)建變量以及類型的對象之前聲明。 delegate void MyDel(int x); 委托類型的聲明看上去與方法的聲明很相似,有返回類型和簽名。返回類型和簽名指定了委托接受的方法的形式。,22,補充:創(chuàng)建委托對象,委托是引用類型,因此有引用和對象。在委托類型聲明之后,我們可以聲明變量并創(chuàng)建類型的對象。有兩種創(chuàng)建委托對象的方式: 第一種是使用帶new運算符的對象創(chuàng)建表達式,new運算符的操作數(shù)組成下:

11、委托類型名; 一組圓括號,其中包含作為調(diào)用列表中第一個成員的方法的名字。方法可以是實例方法,也可以是靜態(tài)方法。 delVar = new MyDel(myInsObj.MyM1);/ 創(chuàng)建委托并保存引用(實例方法) dVar = new MyDel(SClass.OtherM2); / 創(chuàng)建委托并保存引用(靜態(tài)方法),23,補充:創(chuàng)建委托對象,第二種是快捷語法。 delVar = myInsObj.MyM1;/ 創(chuàng)建委托并保存引用(實例方法) dVar = SClass.OtherM2; / 創(chuàng)建委托并保存引用(靜態(tài)方法) 例子:Delegates.sln,24,補充:創(chuàng)建委托對象,25,8.

12、2.5 多重委托,多重委托(multicast delegate)是由兩個或更多的其他委托構(gòu)成的委托。它可以封裝一個或多個方法。當調(diào)用多重委托時,會逐個調(diào)用封裝的所有方法(這對于事件處理特別有用)。,26,8.2.5 多重委托,在C#中,通過使用加法(+)運算符,可以把某個委托添加到一個多重委托中。類似地,通過使用刪除(-)運算符,可以把某個委托從多重委托中刪除。也可以把多個委托添加到一個多重委托中。當多重委托被調(diào)用時,已經(jīng)添加的每個委托就按其被添加的順序調(diào)用。,27,補充:多重委托,MyDel delA = myInstObj.MyM1; MyDel delB = SClass.OtherM

13、2; MyDel delC = delA + delB; 第三個委托是由前兩個委托組成。 例子:Delegates.sln,28,補充:多重委托,29,補充:調(diào)用帶返回值的委托,如果委托有返回值,并且在調(diào)用列表中有一個以上的方法,會發(fā)生下面的情況: 調(diào)用列表中最后一個方法返回的值就是委托調(diào)用返回的值; 調(diào)用列表中所有其它方法的返回值都會被忽略。 例子:Delegates.sln,30,補充:調(diào)用帶引用參數(shù)的委托,如果委托有引用參數(shù),參數(shù)值會根據(jù)調(diào)用列表中的一個或者多個方法的返回值而改變。 在調(diào)用委托列表中的下一個方法時,參數(shù)的新值(不是初始值)會傳給下一個方法。 例子:Delegates.sl

14、n,31,8.3 事件,8.3.1 定義事件 8.3.2 訂閱事件 8.3.3 實現(xiàn)事件 8.3.4 觸發(fā)事件,32,8.3.1 定義事件,在C#中,事件實際上是委托的一種特殊形式。事件是為處理過程特制的更為專業(yè)化的委托。下面是定義事件的格式: modifiers event type name ; 其中modifiers(修飾符)和方法定義中的一樣,可以使用new、public、protect、private、static、virtual、sealed、override、abstract。緊接著要使用關(guān)鍵字event。在名稱之前,還必須確定事件的類型,因為所有的事件是一類特殊的委托,它們都是

15、基于委托的,所以type必須是委托類型。,33,8.3.2 訂閱事件,事件發(fā)生了,如何將它和事件處理的程序聯(lián)系起來呢?這就要用到訂閱器,它是訂閱事件的對象。我們先看看在鬧鈴模擬程序中是如何編輯的,代碼如下: clock.Alarm += new AlarmEventHandler(waking.AlarmRing); 其中,clock是AlarmClock類的一個實例,通過“+=”操作符將事件與新創(chuàng)建的委托聯(lián)系起來。委托的方法是waking.AlarmRing,這是一個事件處理方法,在后面會講到。,34,8.3.2 訂閱事件,訂閱事件也很簡單,通過加運算符(+=)就能完成事件的附加。依此類推,

16、我們可以使用刪除事件運算符(-=),將在事件中分離訂閱器,分離可以防止從發(fā)行器對象發(fā)送來任何后續(xù)事件的通知。 注意:普通的委托和事件間的主要區(qū)別之一是:在附加和分離事件時,只能使用”+=”和”-=”這兩種運算符。,35,8.3.3 實現(xiàn)事件,接收到事件通知后,如何處理?在委托中確定了相關(guān)的處理方法,該方法必須符合事件委托類型的簽名(返回類型和參數(shù)類型)。,36,8.3.3 實現(xiàn)事件,在本例中處理事件的方法如下: public class WakeMeUp public void AlarmRang(object sender, AlarmEventArgs e) 在WakeMeUp類中,定義了

17、一個無返回值的方法AlarmRang,其參數(shù)是object sender和AlarmEventArgs e。,37,8.3.4 觸發(fā)事件,我們要明確:事件不是將各個程序片段串起來的管道,所以,程序也就不能沿著這個管道順流而下。通過這種方式使程序更具有交互性、靈活性和動態(tài)性。本例中觸發(fā)事件的語句是: Alarm(this, e); 其形式上和方法的調(diào)用非常類似。 例子:Events.sln,38,補充:事件的5個源代碼組件,39,補充:使用EventArgs類,EventArgs is the base class for classes containing event data. This

18、class contains no event data; it is used by events that do not pass state information to an event handler when an event is raised. If the event handler requires state information, the application must derive a class from this class to hold the data.,40,補充:使用EventArgs類,EventArgs被設計為不能傳遞任何數(shù)據(jù)。 如果希望傳遞數(shù)據(jù),必須聲明一個從EventArgs繼承的類,使用合適的字段來保存需要傳遞的信息。 盡管EventArgs類實際上并不能傳遞數(shù)據(jù),但它是使用EventHandler委托模式的重要一部分。不管參數(shù)使用的實際類型是什么,object類和EventArgs總是基類。這樣EventHandler就能提供一個對所有事件和事件處理器都通用的名字,只允許2個參數(shù),而不是各自有各自的簽名。,41,補充:通過擴展EventArgs類來傳遞數(shù)據(jù),為了向自己的事件處理程序的第二個參數(shù)傳入數(shù)據(jù),并且又符合標準慣例,我們需要聲明一個派生自EventArgs類的自定義

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論