例項解讀物件導向核心,所有例子基於 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 中,理解了嗎?
我們按一下滑鼠按鈕,觸發某個操作,執行某個方法就是典型的應用。
委託和事件實際上是觀察者模式的應用。
具體的應用場景我就不展開了,大家可以思考。
僅以兩張圖片說明一個例子,啟發大家思考。
觀察者模式結構:
觀察者模式例子:
祝學習進步。