C# 介面 ( C# Interface ) – (C#教學) – 介面就是類別的接口, 就好像在電插一樣, 不同的電器有同一類與電力的接口.
首先, 為何需要介面.
- 編程就像一個布局, 當引用一個class時, 會引用不同的method, property. 如果可以在一段Code內, 引用多個不同的class, 並從這些Class中轉換method, 就大大簡化了編程. 就像電器的例子一樣, 各種不同電器必需要有一個統一的介面來連接電源, 要不是的話, 如果每個不同電器的插頭也不同的話, 必然會引致需要不同類型的接頭, 造成大量的不便, 統一插頭, 接頭的話, 就可大大減少了不便與麻煩.
- 編程多是Teamwork, 如果能有一個主要負責布局, 把整個系統用介面劃分, 這樣布局不但清晰, 而程式員也只需負責當中自己的部分, 責任也清晰.
第二. 介面用法
- 運用介面, 可以在Class 增加一個出口 (method), 計算CLASS 內的LOGIC再劃一導出.
- Adapter概念, 可令程序轉換不同的來源(Method). 在工作實務中, 不同的System, Database, Rest API, Datatable,Class都可能會不同。如有在有些的大公司, 政府部門內, 用的database都可不同, 假設有兩個database, 一個為mysql, 一個為sql server, 假如我要把資料放進不同的資料庫內, 我就可以定立相同的method介面, 在內才call 相關的DB API.
- Dependency Injection: DI就是在程式起始Intialize時, 從介面下的幾個類中, 決定一個作實行Class, 令到日後只需在Class的Constructor中加上介面的Parameter, 就可引用到Class.
- 把多個不同類別中的method作批次處理 (如用for叫引用同一介面的不同的Class). 就算邏輯完全不同, 我們也可以把介面的method加下去的. 例如, 如果我有兩個類別, 一個為冷氣, 一個為水果, 我可以把第三個的用法或處理方法加下去, 如我想在schedule內排序清洗, 就可加入method(Clear()), 內裏的logic也可不同(清法不同). 而也有一些比較普及的, 如存儲存是的ToJson, Console.writeline時的ToString等. 而這不只在OOP, 就算是在DDD, MVC等也可使用.
- 一個介面包含一系列的功能, 可以專門針對某一個作用而作出實作. 例子:
- 如在MVC中, 介面的實作可針對Database的提取, 中問Logic的處理, Page(View)的顯示, 就像Pipeline一樣.
- 可以放在不同的Class中, 如IDisposable, 令各Class也有地方把Class內的Object清理.
第三. 介面例子
以下會介紹 Interface 介面 的基本用法. 結合 for loop, if, Array, Collection, Interface, Inherit等, 可重用當中 Block內的Code. 以下會舉一個簡單的生活例子 ( Inherit 繼承 ), 及一個工作上的例子 ( Interface 介面 ), 以供各位參考:
Interface: |
interface AccountList{ double Calculation(); void LoadItemsFromDB(); } |
Implements Class: |
class PurchasingList : AccountList{ private List<PurchasingItem> items = new List<PurchasingItem>(); public void LoadItemsFromDB(){ //******* } public double Calculation(){ int amount = 0; amount —= CalOrderCost(); amount —= CalOrderDeliveryCost(); return amount; } private double CalOrderCost(){ //******* } private double CalOrderDeliveryCost(){ //******* } } |
Implements Class: |
class InventoryList : AccountList{ private List<InventoryItem> items = new List<InventoryItem>(); public void LoadItemsFromDB(){ //******* } public double Calculation(){ int amount = 0; amount —= CalOrderInventoryFees(); amount —= CalOrderMaintanceFees(); return amount; } private double CalOrderInventoryFees(){ //******* } private double CalOrderMaintanceFees(){ //******* } } |
Implements Class: |
class SellingList : AccountList{ private List<SellingItem> items = new List<SellingItem>(); public void LoadItemsFromDB(){ //******* } public double Calculation(){ int amount = 0; amount —= CalOrderCost(); amount += CalSellingGain(); amount —= CalOrderDeliveryCost(); return amount; } private double CalSellingGain(){ //******* } private double CalSellingCost(){ //******* } private double CalOrderDeliveryCost(){ //******* } } |
Abstract Class Master: |
class ExpenitureReport { //Running Point public void Run(){ List<AccountList> accountLists = new List<AccountList>(); accountLists.Add(new PurchasingList()); accountLists.Add(new InventoryList()); accountLists.Add(new SellingList()); foreach(AccountList item in accountLists){ item.LoadItemsFromDB(); } double sum = 0; foreach(AccountList item in accountLists){ sum += item.Calculation(); } Console.WriteLine(“Sum: ” + sum); } } |
注意事項 |
1) ExpenitureReport.Run 是入口首先把幾個 PurchasingList, SellingList, ExpenitureReport 的Instance放入List<AccountList>內 2) 用foreach 運行LoadItemsFromDB得到Data 3) 用foreach 運行Calculation得到總金頧Sum |
Interface: |
interface ImageFilter{ void Process(); void LoadPixels(); } |
Implements Class: |
class Blur : ImageFilter{ public void FindPixelAverage(){ } public void FindNeignbour(){ } public void Process(){ FindPixelAverage(); FindNeignbour(); } public void LoadPixels(){ //************* } } |
Implements Class: |
class Sharpen : ImageFilter{ void GetEdge(){ } void Blacken(){ } void Process(){ GetEdge(); Blacken(); } void LoadPixels(){ //************* } } |
Implements Class: |
class SellingList : AccountList{ private List<SellingItem> items = new List<SellingItem>(); public void LoadItemsFromDB(){ //******* } public double Calculation(){ int amount = 0; amount —= CalOrderCost(); amount += CalSellingGain(); amount —= CalOrderDeliveryCost(); return amount; } private double CalSellingGain(){ //******* } private double CalSellingCost(){ //******* } private double CalOrderDeliveryCost() { //******* } } |
Abstract Class Master: |
class ImageProcesser{ void Run(){ List<ImageFilter> filters = new List<ImageFilter>(); filters.Add(new Blur()); filters.Add(new Sharpen()); foreach(var filter in filters){ filter.LoadPixels(); filter.Process(); } SetPixels(filters ); } void SetPixels(List<ImageFilter> filters){ //****** } } |
注意事項 |
1) ImageProcesser.Run 是入口首先把幾個 Blur, Sharpen 的 Instance 放入 List<ImageFilter>內 2) 用 foreach 運行 LoadPixel 把Pixel放入Filter 3) 用foreach 運行 Process 得到 計算 4) 最後SetPixels to Image. |
相關頁面:
C#類別 – Class, Method, Inheritance, Interface的基礎用法
C#繼承 – Inheritance 繼承 的基本用法 – 加入 for loop, if, Array, Collection的例子
參考資料: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/interface