第11章委托與事件_第1頁
第11章委托與事件_第2頁
第11章委托與事件_第3頁
第11章委托與事件_第4頁
第11章委托與事件_第5頁
已閱讀5頁,還剩24頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、第第11章章 委托委托(代表代表)與與 事件事件n11.1 委托委托(代表代表)n11.2 事件事件n11.3 事件訪問器事件訪問器n總結(jié)總結(jié)11.1 委托委托 11.1.1 前言前言 11.1.2 定義定義 11.1.3 定義委托對象及實(shí)例化定義委托對象及實(shí)例化 11.1.4 用例用例 11.1.5 進(jìn)一步理解委托進(jìn)一步理解委托 11.1.6 組播組播(多重多重)委托委托返回首頁11.1.1 前言前言 什么是委托什么是委托? 函數(shù)是一個(gè)程序運(yùn)行的代碼段函數(shù)是一個(gè)程序運(yùn)行的代碼段, 調(diào)用該函數(shù)調(diào)用該函數(shù),相當(dāng)于執(zhí)行了這段代碼段相當(dāng)于執(zhí)行了這段代碼段. 有時(shí)有時(shí),我們需要實(shí)現(xiàn)這樣一個(gè)功能我們需要

2、實(shí)現(xiàn)這樣一個(gè)功能: 定義一個(gè)特殊定義一個(gè)特殊”變量變量”,此變量的內(nèi)容為地址此變量的內(nèi)容為地址,-指向某個(gè)函數(shù)的代碼段指向某個(gè)函數(shù)的代碼段(首地址首地址); 這樣這樣,當(dāng)我們當(dāng)我們”調(diào)用調(diào)用”該該”變量變量”時(shí)時(shí),程序就跳轉(zhuǎn)到代碼段去執(zhí)行了程序就跳轉(zhuǎn)到代碼段去執(zhí)行了.n 這個(gè)特殊這個(gè)特殊”變量變量” 就是就是 C,C+中的函數(shù)的指針中的函數(shù)的指針n 因?yàn)橐粋€(gè)函數(shù)有簽名有返回值因?yàn)橐粋€(gè)函數(shù)有簽名有返回值,所以在所以在C#中中,我們將此我們將此”變量變量”看成是某個(gè)看成是某個(gè)”類類”生成的生成的對象對象,這樣我們把定義的這個(gè)這樣我們把定義的這個(gè)”類類” 稱為稱為: 委托委托 (代表代表,代理代理,

3、委派委派) 委托的實(shí)質(zhì)委托的實(shí)質(zhì)n委托實(shí)質(zhì)上一種類型委托實(shí)質(zhì)上一種類型 ,即它的地位處于與類即它的地位處于與類(class),結(jié)構(gòu)結(jié)構(gòu)(struct),枚舉枚舉(enum)一樣一樣n委托在定義好之后委托在定義好之后,必須必須”實(shí)例化實(shí)例化”對象對象”才成使用才成使用.n委托的委托的”對象對象”可以用作可以用作 類類,結(jié)構(gòu)的結(jié)構(gòu)的數(shù)據(jù)成員數(shù)據(jù)成員看待看待(“引用類型引用類型”)n委托的委托的”對象對象”當(dāng)然也可以用作當(dāng)然也可以用作 方法成員的參數(shù)方法成員的參數(shù) 看待看待11.1.2 定義定義 delegate 返回類型返回類型 委托名委托名(形參形參1,);例例1: delegate void

4、Run();/定義了一個(gè)叫定義了一個(gè)叫Run的委托的委托 /Get實(shí)例化后的可以代表實(shí)例化后的可以代表 所有無參數(shù)所有無參數(shù),無返回值那一類的函數(shù)無返回值那一類的函數(shù) /如如 void Main() void Fun(). 例例2: delegate int Handle(string str); /定義了一個(gè)叫定義了一個(gè)叫Handle的委托的委托 /它可以指向它可以指向 int Fun(string str); / int Fun1(string str); / 11.1.3 定義委托對象及實(shí)例化定義委托對象及實(shí)例化 委托名委托名 對象名對象名; 對象名對象名=全名全名.方法名方法名; 委托

5、名委托名 對象名對象名 =new 委托名委托名(初始化參數(shù)初始化參數(shù)); 例例1: public static void Main() Run main; /定義一個(gè)定義一個(gè)Get類型的變量類型的變量main main=Main; / main將將 void Main() 的代碼段指向的代碼段指向 / Run main=new Run(Main); /實(shí)例化實(shí)例化main main(); /執(zhí)行執(zhí)行Main代碼段代碼段,此例將形成死循環(huán)此例將形成死循環(huán) 注意注意: 1.委托僅僅是一個(gè)類型委托僅僅是一個(gè)類型,故一定要定義一個(gè)變量才能使用故一定要定義一個(gè)變量才能使用 2. 變量在初始時(shí)變量在初始時(shí)

6、,只需將只需將”方法名方法名” 賦給它賦給它 3.變量的使用變量的使用, 要把它看成要把它看成 方法的調(diào)用方法的調(diào)用 來理解來理解 11.1.4 用例用例例例1: 委托對象當(dāng)成局部變量例用委托對象當(dāng)成局部變量例用class APP public static void Main() / Run r1; /定義一個(gè)定義一個(gè)Run類型的變量類型的變量r1 Run r1=new Run(Run1); /實(shí)例化實(shí)例化r1,并初始并初始 r1(); /執(zhí)行執(zhí)行Run1代碼段代碼段 A a=new A(); r1=a.Fun1; r1(); /執(zhí)行了執(zhí)行了a.Fun1(); public static v

7、oid Run1() Console.WriteLine(“in Run1”); class A public void Fun1()Console.WriteLine(“in Fun1”); 11.1.4用例用例例例2: 委托對象當(dāng)成類委托對象當(dāng)成類(結(jié)構(gòu)結(jié)構(gòu))的數(shù)據(jù)成員使用的數(shù)據(jù)成員使用class APP public static void Main() B b1=new B(); b1.r=new Run(b1.Fun1); b1.r(); /執(zhí)行了執(zhí)行了 b1.Fun1() b1.r=Run1; b1.r();/相當(dāng)于執(zhí)行了相當(dāng)于執(zhí)行了APP.Run1(); public stati

8、c void Run1() Console.WriteLine(“in Run1”); class B public Run r; public void Fun1()Console.WriteLine(“in Fun1”); 11.1.4 用例用例例例3: 委托對象有參數(shù)和返回值時(shí)的使用委托對象有參數(shù)和返回值時(shí)的使用class APP public static void Main() C c1=new C(); =“張飛張飛”; c1. Active =hack; int result= c1. Active();/執(zhí)行執(zhí)行 Console.WriteLine(

9、result); /了解完成情況了解完成情況 public static int hack(string str) Console.WriteLine(“我是我是:0”, str); /完成砍的動(dòng)作完成砍的動(dòng)作 Console.WriteLine(“我在砍柴我在砍柴”); int 結(jié)果結(jié)果=0; return 結(jié)果結(jié)果; class C public string name; public Handle Active;11.1.5 進(jìn)一步理解委托進(jìn)一步理解委托 1.委托使委托使 動(dòng)作動(dòng)作 名詞化名詞化,是函數(shù)的進(jìn)一步抽象是函數(shù)的進(jìn)一步抽象 2. 委托的出現(xiàn)委托的出現(xiàn),使程序能完成一些特殊的功能

10、使程序能完成一些特殊的功能如如: delegate 菜菜 加工方法加工方法(params 原料原料 f); class 廚師廚師 public 加工方法加工方法 加工加工; class 菜菜 class 原料原料 public string 名稱名稱; . class XX烹調(diào)大全烹調(diào)大全 static public 菜菜 煮煮(params 原料原料 f). static public 菜菜 炒炒(params 原料原料 f) static public 菜菜 蒸蒸(params 原料原料 f) 11.1.5 進(jìn)一步理解委托進(jìn)一步理解委托 1.委托使委托使 動(dòng)作動(dòng)作 名詞化名詞化,是函數(shù)的進(jìn)

11、一步抽象是函數(shù)的進(jìn)一步抽象 2. 委托的出現(xiàn)委托的出現(xiàn),使程序能完成一些特殊的功能使程序能完成一些特殊的功能如如: class XX飯店飯店 public static void Main() 廚師廚師 張三張三=new 廚師廚師(); 原料原料 魚魚=new 原料原料(); 張三張三.加工加工= XX烹調(diào)大全烹調(diào)大全.煮煮; 菜菜 菜菜1=張三張三.加工加工(魚魚);/得到了煮魚得到了煮魚 張三張三.加工加工= XX烹調(diào)大全烹調(diào)大全. 炒炒; 菜菜 菜菜2=張三張三.加工加工(魚魚);/得到了炸魚得到了炸魚 / 將加工方法定義成委托的好處將加工方法定義成委托的好處: 使張三通過使張三通過”不

12、斷地學(xué)習(xí)不斷地學(xué)習(xí)”可以可以”學(xué)會學(xué)會”不同的烹調(diào)方法不同的烹調(diào)方法11.1.5 進(jìn)一步理解委托進(jìn)一步理解委托 3. 作為回調(diào)處理方法的一種機(jī)制作為回調(diào)處理方法的一種機(jī)制 如系統(tǒng)用此方法來接收消息如系統(tǒng)用此方法來接收消息,和處理事件和處理事件 例例: delegate void Handl(string 發(fā)送人發(fā)送人,string 消息消息); class 消息消息 public string 消息名消息名; public Handl 處理處理; class 系統(tǒng)系統(tǒng) public static 消息消息 消息箱消息箱=new 消息消息5; public static void 加入消息隊(duì)列加

13、入消息隊(duì)列(stirng 消息名消息名,Handl 處理方法處理方法) /加入消息加入消息 static void 處理消息處理消息() /定期檢查消息隊(duì)列定期檢查消息隊(duì)列,有信就調(diào)用相應(yīng)的處理方法有信就調(diào)用相應(yīng)的處理方法. 執(zhí)行執(zhí)行 消息箱消息箱i.處理處理(發(fā)送人發(fā)送人1,消息消息1) class 本程序本程序 public static void Main() 系統(tǒng)系統(tǒng).加入消息隊(duì)列加入消息隊(duì)列(“有我的信有我的信”,通知我通知我); public static void 通知我通知我(string 消息消息) console.writeLine(“事情為事情為:”+消息消息); 注意注

14、意: 本例僅為模擬系統(tǒng)信息處理本例僅為模擬系統(tǒng)信息處理,與實(shí)際情況差異較大與實(shí)際情況差異較大!(見見P311,E12-6)11.1.6 組播委托組播委托(廣播廣播,多播多播) 多個(gè)委托代碼可以聯(lián)合起來多個(gè)委托代碼可以聯(lián)合起來,實(shí)現(xiàn)執(zhí)行一個(gè)委托變量而順序調(diào)用多個(gè)代碼段的能力實(shí)現(xiàn)執(zhí)行一個(gè)委托變量而順序調(diào)用多個(gè)代碼段的能力添加添加 委托委托變量委托委托變量=待加入委托變量待加入委托變量1+待加入委托變量待加入委托變量2+; 委托變量委托變量+=待加入委托變量待加入委托變量; 委托變量委托變量+=new 委托委托(方法名方法名); 移除移除 委托變量委托變量 -=待加入委托變量待加入委托變量; 委托變

15、量委托變量 -=new 委托委托(方法名方法名); 例例: p311 E12-6 重要重要!,理解此知識點(diǎn)會更容易理解事件理解此知識點(diǎn)會更容易理解事件 11.2 事事件件 11.2.1 前言前言 11.2.2 定義和簡單示例定義和簡單示例 11.2.3 使用系統(tǒng)定義的類型使用系統(tǒng)定義的類型11.2.1 前言前言 想象一下想象一下: 生活中的事件生活中的事件 n歷史歷史 赤壁之戰(zhàn)赤壁之戰(zhàn) 9.18事變事變 新中國成立新中國成立n我的人生我的人生 當(dāng)我當(dāng)我XX歲生日歲生日, 當(dāng)我大學(xué)畢業(yè)當(dāng)我大學(xué)畢業(yè),我的第一份薪水我的第一份薪水n門門 被打開被打開, 被關(guān)閉被關(guān)閉 n按鈕按鈕 被按下被按下,被放開

16、被放開 ,正被按下正被按下, 正被放開正被放開在軟件中在軟件中,為了讓類為了讓類 和類的實(shí)例和類的實(shí)例 之間更好的通信之間更好的通信,C#為我們定義了事件為我們定義了事件(event) 事件是一種對象間傳遞消息的一種方式事件是一種對象間傳遞消息的一種方式.通過事件通過事件, 可以將可以將 事件名與事件名與 具件事件聯(lián)系起來具件事件聯(lián)系起來. 如如: n 每個(gè)人都有每個(gè)人都有XX 歲生日事件歲生日事件, 但是每個(gè)人的但是每個(gè)人的XX歲生日所發(fā)生的都不相同歲生日所發(fā)生的都不相同.n 每個(gè)按鈕都有每個(gè)按鈕都有 按下按下,放開事件放開事件,都每個(gè)按鈕按下都每個(gè)按鈕按下,放開的處理和結(jié)果都不相同放開的處

17、理和結(jié)果都不相同.11.2.2 定義和簡單示例定義和簡單示例 事件是類的成員事件是類的成員,定義定義: 修飾符修飾符 event 委托類型委托類型 事件名事件名;.例例1: class Door public event EventHandler Opening ; /正在開門正在開門 public event EventHandler Opened ; /已開門已開門 public event EventHandler Closing; /正在關(guān)門正在關(guān)門 public event EventHandler Closed; /已關(guān)門已關(guān)門 例例2: class Button event Ev

18、entHandler Cliek ; /單擊單擊 event EventHandler DubClick; /雙擊雙擊 假設(shè)假設(shè): EventHandler 委托原型為委托原型為 delegate void EventHandler(); 11.2.2 定義和簡單示例定義和簡單示例進(jìn)一點(diǎn)完善進(jìn)一點(diǎn)完善 門門 類類 ,加入兩個(gè)動(dòng)作加入兩個(gè)動(dòng)作: 開門開門 關(guān)門關(guān)門 例例1: class 門門 public event Event_Handler Opening ; /正在開門正在開門 public event Event_Handler Opened ; /已開門已開門 public event

19、 Event_Handler Closing; /正在關(guān)門正在關(guān)門 public event Event_Handler Closed; /已關(guān)門已關(guān)門 public void Open()if(Opening!=null) Opening(); /發(fā)送正在開門消息發(fā)送正在開門消息 /做開門的動(dòng)作做開門的動(dòng)作 / if(Opened!=null) Opened(); /發(fā)送門已被打開的消息發(fā)送門已被打開的消息 public void Close()if(Closing!=null) Closing (); /發(fā)送正在關(guān)門消息發(fā)送正在關(guān)門消息 /做關(guān)門的動(dòng)作做關(guān)門的動(dòng)作 / if(Closed!

20、=null) Closed (); /發(fā)送門已被關(guān)閉的消息發(fā)送門已被關(guān)閉的消息 11.2.2 定義和簡單示例定義和簡單示例如何使用如何使用 門門 例例1: class 房子房子 public static 門門 前門前門= new 門門(); ; /定義定義,并實(shí)例化一扇門并實(shí)例化一扇門 public static void Main() 前門前門.Opening += new Event_Handler(OnOpening);/把處理方法掛到把處理方法掛到Opening方法上去方法上去 前門前門.Opened += new Event_Handler(OnOpened);/把處理方法掛到把處

21、理方法掛到Opened方法上去方法上去 while(true) Console.WriteLine(“請輸入動(dòng)作請輸入動(dòng)作: 0-開門開門 C-關(guān)門關(guān)門 q-結(jié)束程序結(jié)束程序”); switch(Console.ReadLine() case “o”: 前門前門.Open();/開門開門 ;break; case “c”: 前門前門.Close();/關(guān)門關(guān)門;break; case “q”: return ; public static void OnOpening() Console.WriteLine(“門正被我打開門正被我打開!”); public static void OnOpen

22、ed() Console.WriteLine(“門已打開門已打開!”); . 11.2.2 定義和簡單示例定義和簡單示例修飾符修飾符 : 訪問修飾符訪問修飾符 public proteced private internal . 其它修飾符其它修飾符 new static virtual seadle override abstract 意義意義:(見類的成員修飾符見類的成員修飾符)事件類型事件類型: 事件的類型一定是委托類型事件的類型一定是委托類型; 其其:1.可以自行定義可以自行定義(見例見例1,例例2); 2.也可以使用系統(tǒng)已定義好的類型也可以使用系統(tǒng)已定義好的類型; 例例: deleg

23、ate void EventHandler(objcet send ,XXXEventArgs e) 參數(shù)參數(shù): send 通常是指引發(fā)事件的對象通常是指引發(fā)事件的對象, e 是用來存放事件發(fā)生時(shí)傳送來的數(shù)據(jù)是用來存放事件發(fā)生時(shí)傳送來的數(shù)據(jù) (注意注意: 類型為類型為XXXEventArgs ,均派生于均派生于EventArgs,這個(gè)系統(tǒng)定義好的類這個(gè)系統(tǒng)定義好的類) 返回值返回值 void 3. 也可以按也可以按 系統(tǒng)的要求系統(tǒng)的要求,派生參數(shù)派生參數(shù) e 的類型的類型,以得到不同的委托以得到不同的委托 11.2.3 使用系統(tǒng)定義的委托類型使用系統(tǒng)定義的委托類型例例: 進(jìn)一點(diǎn)改進(jìn)進(jìn)一點(diǎn)改進(jìn)

24、例例1/定義委托定義委托 delegate void EventHandler(object send ,DoorEventArgs e);/處理處理”門門” 事件可能需要用到的數(shù)據(jù)對象事件可能需要用到的數(shù)據(jù)對象 class DoorEventArgs :EventArgs public string Message; public DoorEventArgs(string m) Message = m; 11.2.3 使用系統(tǒng)定義的委托類型使用系統(tǒng)定義的委托類型/門門的的定義定義 class Door public string 名稱名稱; public event EventHandler

25、 Opening ; /正在開門正在開門 public event EventHandler Opened ; /已開門已開門 public event EventHandler Closing; /正在關(guān)門正在關(guān)門 public event EventHandler Closed; /已關(guān)門已關(guān)門 public Door() public Door(string 名名)名稱名稱=名名; public void Open(object send) if(Opnening!=null) Opening(send, new DoorEventArgs(this.名稱名稱); /Do somethi

26、ng if(Opned!=null) Opened(send, new DoorEventArgs(this.名稱名稱); public void Close(object send) if(Closeing!=null) Closing(send, new DoorEventArgs(this.名稱名稱); /Do something if(Closed!=null) Closed(send, new DoorEventArgs(this.名稱名稱); 11.2.3 使用系統(tǒng)定義的委托類型使用系統(tǒng)定義的委托類型/事件驅(qū)動(dòng)的事件驅(qū)動(dòng)的”主程序主程序” class 房子房子 public str

27、ing 名稱名稱; public Door 大門大門; public 房子房子() public 房子房子(string 名名) 大門大門 = new Door(大門大門); /定義定義,并實(shí)例化一扇門并實(shí)例化一扇門 名稱名稱 = 名名; public void Init() 大門大門.Opening += new EventHandler(OnOpening);/把處理方法掛到把處理方法掛到Opening方法上去方法上去 大門大門.Opened += new EventHandler(OnOpened);/把處理方法掛到把處理方法掛到Opened方法上去方法上去 大門大門.Closing +

28、= new EventHandler(OnClosing); 大門大門.Closed += new EventHandler(OnClosed); public void OnOpening(object send, DoorEventArgs e) Console.WriteLine(0 的的1正在打開正在打開, (房子房子)send).名稱名稱, e.Message); public void OnOpened(object send, DoorEventArgs e) Console.WriteLine(0 的的1已打開已打開, (房子房子)send).名稱名稱, e.Message);

29、 11.2.3 使用系統(tǒng)定義的委托類型使用系統(tǒng)定義的委托類型/底層系統(tǒng)底層系統(tǒng)class App static 房子房子 h; public static void Main() Init();/系統(tǒng)初始化系統(tǒng)初始化 do Console.WriteLine(*); Console.WriteLine(請輸入動(dòng)作請輸入動(dòng)作: o-開門開門 c-關(guān)門關(guān)門 e-清除屏幕清除屏幕 q-結(jié)束程序結(jié)束程序); Console.WriteLine(*); switch (Console.ReadLine() case o: h.大門大門.Open(h) ;break; case c: h.大門大門.Clo

30、se(h);break; case e: Console.Clear(); break; case q: return; while (true); public static void Init() h = new 房子房子(陳公館陳公館); h.Init();/初始化初始化 11.3 事件訪問器事件訪問器n11.3.1 前言前言n11.3.2 定義定義11.3.1 前言前言n為什么使用事件訪問器為什么使用事件訪問器? 事件可以理解為是委托的一種特例事件可以理解為是委托的一種特例. 事件在使用上比委托受了一些限制事件在使用上比委托受了一些限制(為了更有意義的使用事件為了更有意義的使用事件)

31、1.事件的類的成員事件的類的成員 ,用用event 定義定義 委托是一種類型委托是一種類型 , 委托的實(shí)例才是類的成員委托的實(shí)例才是類的成員 delegate void Handle(); /委托委托 class A public event Handle click;/事件成員事件成員 public Handle Fun;/委托成員委托成員 2. 事件僅能用事件僅能用 += - = 加掛或脫離方法加掛或脫離方法 委托的實(shí)例對象可以用委托的實(shí)例對象可以用=號與方法掛勾號與方法掛勾,也可以使用也可以使用+=,也可以使用也可以使用- = 脫勾脫勾 click += new Handle(B.fun); click -= new Handle(B.fun); Fun=new Handle(); Fun=B.fun; Fun=null; Fun+=new Handle(B.fun); Fun-=new Handle(B.fun); Fun +=B.fun; 11.3.1 前言前言n為什么使用事件訪問器為什么使用事件訪問器?3. 系統(tǒng)在編譯時(shí)會默認(rèn)為

溫馨提示

  • 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論