第五章 介面/集合/泛型 注意: 本投影片僅供本書上課教師使用,非經同意請勿上網轉載或供拷貝
5-1 介面與實作 多重繼承 是指某類別同時自多個父類別衍生出來,也就是 子類別只能繼承自某一特定父類別而無法同時繼承 多個父類別。 C# 提供繼承機制只能單一繼承某個父類別, 未提供多重繼承, 解決方案就是透過 介面 (Interface)
5-1 介面與實作 介面可多重繼承其他介面。 介面很像類別,介面是提供有關連 沒繼承關係的類別一些規格。 介面很像類別,介面是提供有關連 沒繼承關係的類別一些規格。 定義介面時只能對 方法做宣告,再透過類別來實作 即該方法的程式碼在該類別內撰寫 介面要經類別實作才有用 C# 類別不能直接繼承多個類別 只能繼承一個基底類別,但可繼承多個介面。 可運用介面做到多重繼承要做的事情。
5-1 介面與實作 Continue… 解決多重繼承 透過介面,由於介面可多重繼承其他介面 來實現某些特定需求。 定義介面時 只對方法做宣告,再透過類別來實作。 方法的程式碼在該類別內撰寫。 介面要經類別實作才有用。 類別只能繼承一個基底類別 可繼承多個介面 運用介面做到多重繼承要做的事情。
5-1 介面與實作 Continue… C# 編寫多重繼承方式 使用interface關鍵字來達到多重介面 任何類別都可在不管類別的階層架構下實作介面 來達到多重繼承的目的。
一. 介面的定義 介面像類別可定義屬性、方法、事件和 索引子等成員。 成員可無或多個。 不允許為常數、欄位、建構函式、解構函式、型別、靜態成員。
介面和類別不同處: 介面不提供實作,介面必須經類別來實作。 一個類別可實作一個或多個介面 一個介面也可同時給多個類別實作。 類別可透過介面的實作,達到多型效果。 介面是制訂類別實作的標準,不是用來 做功能繼承。
介面的特點: 介面不可被實體化,不可用 new 來建立介面。 若類別繼承介面 該類別要實作介面的所有成員。 類別能繼承一個以上的介面 介面亦可繼承一個以上的介面。 定義介面時不允許使用 public、private、 static 存取修飾詞。 一個類別只能繼承一個父類別 一個類別可實作(繼承)多個介面。
定義介面語法:
一般以大寫字母 I 開頭。 介面所定義的成員會自動成為public公用成員 不能使用 private、protected修飾詞宣告。 介面成員可有 0 個或多個。 介面的屬性是用自動屬性實作定義。 介面所定義的方法只能原型宣告, 只有方法名稱沒有實作 真正的方法實作(指程式碼)留給相關連 的類別來進行。
定義名稱為 IConvert 介面含有下列成員: interface IConvert { double Mult { get; set; } // 倍率屬性 void Convert(double l); // 換算長度的方法原型 }
二. 如何實作介面
參閱本書 5-5 頁
三. 一個類別如何實作多個介面
參閱本書 5-8頁
四.介面實作多型
參閱本書 5-12頁
5-2 委派 (Delegate) 一般呼叫方法不允許將方法當引數傳遞。 委派可將方法當引數傳遞。 事件處理函式就是透過委派叫用的方法。 委派是參考方法的一種型別。 宣告的變數是用來存放被呼叫方法的位址。 委派變數的內容是可經設定而動態改變 改變不同的方法位址時,該變數便可呼叫 不同的方法。
一、連結指定方法的委派
參閱本書 5-18頁
二、連結匿名方法的委派 連結指定方法的委派是傳統的委派方式。 另提供連結匿名方法的委派方式。連結的方法無須宣告,直接將方法內容以程式區塊當作引數傳遞。
三、Lambda表示式的委派方式 目的是要建立一個委派物件 這個委派物件的內部要保存一個函式參考 該函式是用大括弧 { } 包住的匿名方法, 並用「=>」傳入引數。 將上範例連結匿名的委派方式改用Lambda 表示式的敘述:
5-3 集合 (Collection) 是將一群相關資料聚集起來, 再以特定方式來處理或存取這些資料。 是將一群相關資料聚集起來, 再以特定方式來處理或存取這些資料。 System.Collections 命名空間內包含定義不同 物件集合的介面和類別 它定義多種物件的集合 清單、佇列、堆疊、位元陣列、雜湊表 和字典。
清單、佇列、位元陣列、雜湊表和字典等類別 都存在System. Collections 命名空間: using System 清單、佇列、位元陣列、雜湊表和字典等類別 都存在System. Collections 命名空間: using System.Collections; 未用 using 匯入命名空間,在程式中有參用 這些類別物件名稱的前面都必須加上 System.Collections.ArrayList book = new System.Collections.ArrayList(); 建議採using 書寫,使得敘述看起來精簡: using System.Collections; ArrayList book = new ArrayList();
5-4 ArrayList 類別 ArrayList 陣列串列類別與Array 陣列相似。 ArrayList 功能比 Array 強。 ① ArrayList類別所宣告的變數為集合物件,集合物件 元素可存放不同資料型別,如:int、string、bool、 結構、物件…等型別。 ② ArrayList集合物件處理元素的方式,是依索引值順序 存放,但事先不必宣告物件的容量大小,只需將新元素 新增或插入。 ③ ArrayList集合物件的容量會依據需求自動擴充,元素 下限索引為0,只有一個維度。
一. ArrayList 類別集合物件常用的屬性與方法
二. ArrayList 類別物件的宣告
【例1】宣告 ArrayList 的類別物件book using System.Collections; ArrayList book = new ArrayList(); 【例2】使用 Add()方法加入不同資料型別的資料 至arylst1 陣列串列集合中 ArrayList arylst1 = new ArrayList(); arylst1.Add("Alice"); arylst1.Add("Bob"); arylst1.Add(168); arylst1.Add(true);
將上面宣告和建立 arylst1 陣列物件實體時允許和 初值設定共五行敘述合拼成一行敘述: ArrayList arylst1 = new ArrayList { "Alice", "Bob", 168 , true }; 執行後實際串列內容(串列索引由零開始算起):
【例3】新增 “David” , “Eric” 字串常數到陣列串列最後 arylst1 【例3】新增 “David” , “Eric” 字串常數到陣列串列最後 arylst1.AddRange(new string[2] {"David","Eric"}); 執行後串列內容:
[實作] 上例 整合成一個完整程式arrayList1.sln) : 參閱 5-30頁
參閱本書 5-32頁
5-5 Queue 佇列類別 佇列類別物件如袋子兩端都有口 是一種先進先出(FIFO)或後進後出(LILO)的集合 該集合的元素是一個線性串列資料結構,存放資料時 從串列一端依序加入;刪除時從串列的另一端移除 最早存放資料最先移除,最後存放資料最晚移除。 程式中參用 Using 匯入 System.Collections 命名空間。
Queue 物件常用屬性與方法:
【例1】宣告建立Queue類別物件QName Queue QName = new Queue(); string[] drink = {"David", "Tom", "Jack", "Mary", "Bob"}; for (int i = 0; i < aryName.Length; i++) { QName.Enqueue(aryName[i]); 尾部插入元素 } 【例3】由Queue類別物件中,由最前面移除一個元素 QName.Dequeue(); 【例4】清除Queue類別物件中所有元素變成空佇列 QName.Clear();
參閱本書 5-34頁 【實作範例】 使用Queue 類別建立一個 QName 物件用來存放同學 姓名,將上面例 1~4 每步驟操作結果,使用 printout() 方法顯示目前佇列中的內容:
5-6 Stack堆疊類別 堆疊類別物件有如有底的袋子出入口只有一個。 是一種 後進先出(LIFO)的集合 集合的元素屬線性串列資料結構。 加入(Push)資料時會疊在串列的 最上(前)端 刪除(Pop)資料也是從串列的 最上(前)端開始移除。 程式中有用到此類別 用 using 匯入System.Collections命名空間。
Stack 物件常用的屬性與方法
參閱本書 5-38頁
5-7 Hashtable 雜湊表類別 雜湊函式 雜湊表是資料結構的一種,它根據鍵值配合 一個函式把值映射到資料表中一個位置,以加 快找尋資料的速度。 一個良好的雜湊演算法資料碰撞發生率很低。 雜湊表是根據鍵值的雜湊程式碼組成的索引鍵/ 值組集合。 Hashtable 物件的集合元素中,在值方面會有 群組 稱為「雜湊桶」。
Hashtable 物件常用屬性與方法
參閱本書 5-42頁
5-8 SortedList 排序清單類別 SortedList 類別物件用法與 Hashtable 雜湊表 類別相似,都是索引鍵與值配對的集合。 SortedList 串列會依照集合內元素索引鍵排序。 【實作範例】 試由鍵盤輸入五筆資料,每筆資料包含姓名(name) 和 成績(score),依序置入SortedList排序清單類別物件SLScore,資料加入時會自動按照鍵值排序,輸入完 畢使用foreach逐一顯示所有的姓名鍵值和對應成績值。 參閱本書 5-43頁
5-9 泛型 (Generics) 使用泛型的原因? 泛型是能以未定型別的引數來宣告類別、 介面程序、方法…待實際使用 new 建立物件 或呼叫使用時,再指定引數的型別。 程式中使用泛型 - 可讓不同型別去做相同動作的事。 - 不需為引數型別不同而重複編寫功能相同 方法成員,物件可共用此方法成員。 泛型類別和方法 可達到重複使用性、型別安全和高效率。
一. 泛型類別的定義
二. 泛型方法的定義
三. 如何叫用泛型 泛型類別經宣告後,便可用 new 建立不同資料型別的物件實體 語法中資料型別必須以角括號括住,因它有一個型別 參數 T 可代表任何資料型別,該資料型別會取代所 呼叫方法成員內的對應的型別參數。 寫法:
參閱本書 5-51頁
參閱本書 5-49頁 輸出畫面
四. 內建泛型類別 List 在System.Collections.Generic 命名空間內, .NET Framework 內建許多泛型類別,如: List、Queue、Stack、Dictionary等類別。 內建泛型類別,不必經 new宣告可直接建立該類別 物件,並用該物件的成員。 泛型類別 List 串列的型式為 List<T>,T為型別參數, T 可代表任何型別。 建立的物件用來存放串列的資料。比陣列更有彈性, 串列可動態增長或縮減,串列可儲存任何型別 屬性與方法的用法與 ArrayList 集合類別相近。 由於類別 List<T> 為系統內建,故不必宣告,可直接 建立物件。
參閱本書 5-54頁
五. 內建泛型類別 Dictionary 泛型類別 Dictionay 的型式 Dictionary<Tkey, TValue> 提供從一組索引鍵(key)至一組值(value)的對應, 加入Dictionary(字典)類別物件中的每個項目都由其 關聯索引鍵和值所組成。 使用索引鍵擷取值的速度非常快。 Dictionary<TKey, TValue> 中每個索引鍵都必須 是唯一且不能 null。 Dictionary 泛型類別物件的屬性及方法之用法與Hashtablet 集合類別物件相近。
[範例實作] 為泛型實作 Dictionary 類別物件的基本使用,其中元素配對的所代表的意義: -索引鍵(Key)為文件類型、 - 值(Value)為執行程式。 參閱本書 5-55頁
參閱本書 5-57頁
輸出結果
本章結束 Take a Break …