[讀書筆記 ]Stephens' C# Programming with Visual Studio 2010 24-Hour Trainer 第二十七章

  • 1032
  • 0
  • 2012-11-06

閱讀Stephens' C#教材第二十七章筆記

Chapter 27 Using Interfaces.

 
本章將介紹介面(Interface),在.Net程式中,介面就像一種合約,在介面中定義的屬性、方法及事件,在類別中實作時必須滿足介面中的定義。
 
本章將介紹兩種使用介面的優點:multiple inheritance 及code generalization。
 
multiple inheritance(多重繼承):類別可以從不只一個介面繼承。假如你定義了一個Vehicle類別,具有屬性如:NumberOfPassengers, MilesPerGallon及NumberOfCupHolders,透過這個母類別透過繼承產生出其他交通工具的類別如Car, PickupTruck及Bicycle。
另外一個類別Domicile類別,具有屬性如:SquareFeet, NumberOfBedrooms及NumberOfBathdrooms,透過這個母類別透過繼承產生出其他住所的類別如Apartment, Condo及VacationHome。
如果現在想要需要一個MotorHome的類別,同時具備Vehicle及Domicile類別的所有屬性,但是很抱歉,在 C#中只能,。
但是慶幸的是繼承的類別只能有一個,但是可以實作多個介面。上面的案例,可以將Domicile類別轉成IDomicile介面(為了區別介面與類別,通常建議介面命名前面加一個大寫I字母),MotorHome類別繼承Vehicle類別然後實作IDomicile介面。
 
code generalization(通用程式碼):由於介面本身並不會進行型別檢查,所以可以達到通用程式碼的功能,例如以下有一個Listbox控制項會顯示一個陣列,程式如下:
        private void DisplayValues(String[] items)
        {
            itemsListBox.Items.Clear();            
            foreach (string item in items)
            {
                itemsListBox.Items.Add(item);
            }
        }
 
但稍晚你又需要一個新功能要顯示List的內容,程式如下:
        private void DisplayValues(List items)
        {
            itemsListBox.Items.Clear();
            foreach (string item in items)
            {
                itemsListBox.Items.Add(item);
            }
        }
這兩個程式基本上除了參數型別不一樣,其他都一樣,但是如果程式有異動,可以需要修改多處地方,增加程式修改的複雜性。
此時可以讓介面發揮所長,提供協助。系統本身提供有IList的介面,只要將string[]及List<string>實作IList<string>,就可以用IList<string>取代string[]或List<string>,將兩段程式合併如下:
        private void DisplayValues(IList items)
        {
            itemsListBox.Items.Clear();
            foreach (string item in items)
            {
                itemsListBox.Items.Add(item);
            }
        }
介面實作只要在類別宣告的後面加上介面名稱就可以了
        class DrawableCircle : IDrawable
        {
            ...
    
        }

然後開發平台會出現提示如下圖 所示,IDrawable的I會出現虛線底線提醒你。

 
如果游標移到該底線,會看到下圖,開發平台會問你是否要實作介面
 
如果點下實作介面,那麼開發平台會自動為你建立程式碼如下圖,程式碼中會將所有該介面所定義的屬性、方法與事件產生在程式區塊中,你只要將區塊中的程式碼改寫即可。
 
 
至於介面的定義方式,大部分與類別相同,最大兩點不同處在:
使用interface關鍵字而非class進行宣告
所宣告的屬性、方法與事件不需要撰寫任何程式碼在區塊中
例如:
    interface IDrawable
    {
        int X { get; set; }
        int Y { get; set; }
        Brush Background { get; set; }
        Pen Foreground { get; set; }
        void Draw(Graphics gr);
    }

Drawables程式示範介面IDrawable的宣告,並且三個類別時做了此介面,可以畫出不同的形狀,如下圖:

 

FastCars程式示範介面IComparer的實作,並且用於汽車的比較,如下圖:

 
TRY IT就是以一開始所舉的例子,使用IList介面協助建立MotorHome類別,具有兩個類別的組合屬性