2017年9月27日 星期三

C# : 以明確方式實作介面 (Explicit Interface Implementation)練習

在這個練習中,我們使用不同的命名空間,區隔出同樣的名稱的兩個介面和要實作出這兩個介面類別的定義,在底下的程式碼,是沒有使用明介介面實作,而是使用了實作介面這個功能。

了解更多關於 [明確介面實作的使用方式
了解更多關於 [C# 程式設計手冊 



實作介面

當 Visual Studio 提示 IContron 介面沒有實作的提示時候,將游標移動到燈泡提示上,請選擇 實作介面,此時,在 SampleClass 類別內,就會自動幫我們產生出這個介面需要提供的方法定義;另外,因為,我們在這個類別中需要繼承兩個介面,不過,這兩個介面都只需要實作出同一個方法,因此,當我們在類別中實作出 public void Paint() {...} 方法之後,就同時滿足了這兩個介面的需求。
實作介面
namespace 沒有明確實作介面
{ 
    interface IControl
    {
        void Paint();
    }
    interface ISurface
    {
        void Paint();
    }
    class SampleClass : IControl, ISurface
    {
        // Both ISurface.Paint and IControl.Paint call this method. 
        public void Paint()
        {
            Console.WriteLine("要執行的是 SampleClass 實作的 Paint 方法");
        }
    }
}

執行測試

我們在這裡建立一個型別為 沒有明確實作介面.SampleClass 的物件,指定給型別為 沒有明確實作介面.SampleClass 的物件變數內;接著分別將這個物件,轉型為兩個型別為 沒有明確實作介面.IControl 與 沒有明確實作介面.ISurface 的介面類型物件變數。
當我們執行後,我們發現到,不論是透過物件變數的型別為類型或者是介面的物件變數,所執行的 Paint()的方法都是指向這個類別中的實作方法。
沒有明確實作介面.SampleClass sc = new 沒有明確實作介面.SampleClass();
沒有明確實作介面.IControl ctrl = (沒有明確實作介面.IControl)sc;
沒有明確實作介面.ISurface srfc = (沒有明確實作介面.ISurface)sc;

sc.Paint();
ctrl.Paint();
srfc.Paint();
Console.WriteLine($"Press any key for continuing...{Environment.NewLine}");
Console.ReadKey();
這是執行後的輸出內容
要執行的是 SampleClass 實作的 Paint 方法
要執行的是 SampleClass 實作的 Paint 方法
要執行的是 SampleClass 實作的 Paint 方法
Press any key for continuing...

以明確方式實作介面

這是微軟官方文件,對於明確介面實作的定義
如果類別實作了兩個包含相同簽章之成員的介面,則在類別上實作該成員會導致兩個介面都將該成員當做實作 (Implementation) 使用
當 Visual Studio 提示 IContron 介面沒有實作的提示時候,將游標移動到燈泡提示上,請選擇 以明確方式實作介面
明確介面實作
底下為我們要測試的介面與類別宣告的程式原始碼,我們在類別 SampleClass內看到,這裡分別定義了這三個介面需要實作的方法
  • public void Paint()
  • void IControl.Paint()
  • void ISurface.Paint()
這三個實作方法將會輸出不同的文字,現在,讓我們透過實際測試的程式碼,看看這三個方法要如何使用呢?
namespace 有明確實作介面
{
    interface IControl
    {
        void Paint();
    }
    interface ISurface
    {
        void Paint();
    }
    class SampleClass : IControl, ISurface
    {
        public void Paint()
        {
            Console.WriteLine("要執行的是 SampleClass 實作的 Paint 方法");
        }
        void IControl.Paint()
        {
            Console.WriteLine("要執行的是 IControl 介面明確實作的 Paint 方法");
        }

        void ISurface.Paint()
        {
            Console.WriteLine("要執行的是 ISurface 介面明確實作的 Paint 方法");
        }
    }
}

執行測試

我們在這裡建立一個型別為 有明確實作介面.SampleClass 的物件,指定給型別為 有明確實作介面.SampleClass 的物件變數內;接著分別將這個物件,轉型為兩個型別為 有明確實作介面.IControl 與 有明確實作介面.ISurface 的介面類型物件變數。
當我們執行後,我們發現到,若該物件變數的宣告型別為該類別,而且所指向的實際物件型別也是該類別,則呼叫 Paint() 的方法,將會執行在該類別中的 public void Paint() 法。
不過,當我們將 new 有明確實作介面.SampleClass() 所產生的物件,轉型成為其他介面的時候,並且執行這個介面的 Paint() 的方法,我們會發現,此時,會依據當時轉型成功的介面類型,執行 void IControl.Paint() 或者 void ISurface.Paint() 方法。
有明確實作介面.SampleClass sc2 = new 有明確實作介面.SampleClass();
有明確實作介面.IControl ctrl2 = (有明確實作介面.IControl)sc2;
有明確實作介面.ISurface srfc2 = (有明確實作介面.ISurface)sc2;

sc2.Paint();
ctrl2.Paint();
srfc2.Paint();
((有明確實作介面.IControl)sc2).Paint();
((有明確實作介面.ISurface)sc2).Paint();
Console.WriteLine($"Press any key for continuing...{Environment.NewLine}");
Console.ReadKey();

底下內容為執行後的輸出文字
要執行的是 SampleClass 實作的 Paint 方法
要執行的是 IControl 介面明確實作的 Paint 方法
要執行的是 ISurface 介面明確實作的 Paint 方法
要執行的是 IControl 介面明確實作的 Paint 方法
要執行的是 ISurface 介面明確實作的 Paint 方法
Press any key for continuing...

了解更多關於 [明確介面實作的使用方式
了解更多關於 [C# 程式設計手冊 






沒有留言:

張貼留言