實例解讀面向對象核心,所有例子基於 C#,涉及我們實務中最常關心的問題: 1、封裝、繼承、多態; 2、抽象類、介面; 3、委托、事件。 三、委托和事件 通俗的說,我們使用委托的目的是“實現將方法作為參數傳遞的效果”,直接結合例子說明。 我們還是用基於上次的示例往下更改。 場景設定:根據圖形的不同,返 ...
實例解讀面向對象核心,所有例子基於 C#,涉及我們實務中最常關心的問題:
1、封裝、繼承、多態;
2、抽象類、介面;
3、委托、事件。
三、委托和事件
通俗的說,我們使用委托的目的是“實現將方法作為參數傳遞的效果”,直接結合例子說明。
我們還是用基於上次的示例往下更改。
場景設定:根據圖形的不同,返回不同的面積演算法。
// 參數為圖形形狀, 返回該圖形的面積計算公式 public string GetAreaAlg(string shapeName) { if (shapeName=="矩形") { return "長 × 寬"; } else if (shapeName == "圓形") { return "pi * r * r"; } else { return "該圖形面積演算法未定義"; } }
當圖形越來越多時,方法體中的分支就會膨脹。
這時候我們很自然的想到,如果我們可以直接將方法作為參數傳進來,那麼就可以不需要這些分支了。
類似如下:
public string GetAreaAlg(某種類型 計算面積公式的方法) { 執行此 計算面積公式的方法; }
好了,我們順著這個思路改造一下:
#region delegate相關演示 //聲明一個委托 public delegate string GetAreaAlgDelegate(); // 矩形的面積演算法 public string GetRectangleAreaAlgorithm() { return "矩形的面積演算法:長 × 寬"; } // 圓形的面積演算法 public string GetRCircleAreaAlgorithm() { return "圓形面積公式:pi * r * r"; } public string GetAreaAlg(GetAreaAlgDelegate GetAlgorithm) { return GetAlgorithm(); } #endregion
這個時候,在Home/Index中直接調用即可:
string strAlgorith = GetAreaAlg(GetRectangleAreaAlgorithm);
加個斷點調試一下,可以看到返回了 矩形的面積演算法:長 × 寬
理解了嗎?我們來小結一下。
委托是對函數的封裝,可以當作給方法的特征指定一個名稱,我們可以和普通的參數做類比來理解。
委托是一個類,它定義了方法的類型,使得可以將方法當作另一個方法的參數來進行傳遞,這種將方法動態地賦給參數的做法,可以避免在程式中大量使用分支語句,同時使得程式具有更好的可擴展性。
接下來再談下事件。
事件是委托的一種特殊形式,當事件發生時,事件對象通知處理過程。
我們改造下我們的例子,加一句就行,緊接著聲明委托下麵聲明事件:
//聲明一個委托 public delegate string GetAreaAlgDelegate(); // 聲明一個事件 public event GetAreaAlgDelegate GetArea;
同樣在Home/Index中,調用時先登記事件:
GetArea += new GetAreaAlgDelegate(GetRCircleAreaAlgorithm); string res= GetArea();
加個斷點調試一下,可以看見返回了 圓形面積公式:pi * r * r
我們通過實例化委托,將GetRCircleAreaAlgorithm方法登記到事件 GetArea 中,理解了嗎?
我們按一下滑鼠按鈕,觸發某個操作,執行某個方法就是典型的應用。
委托和事件實際上是觀察者模式的應用。
具體的應用場景我就不展開了,大家可以思考。
僅以兩張圖片說明一個例子,啟發大家思考。
觀察者模式結構:
觀察者模式例子:
祝學習進步。