2017年9月25日 星期一

C# : 練習如何設計 多載 Overloading 與 覆寫 Overriding

相信很多人對於 C# 的多載 Overloading 與 覆寫 Overriding 都無法了解到其中的差異,我們在這裡做個簡單的說明


了解更多關於 [成員多載的使用方式
了解更多關於 [override (C# 參考)的使用方式
了解更多關於 [C# 程式設計手冊]


  • 多載 Overloading
    這是在同一個型別中,對於同一個函式的名稱,卻有不同的參數類型與數量(不含回傳值的型別),此時,要呼叫這個函式的時候,就需要根據所傳入的引數來判斷;通常在 Visual Studio 內,會有 IntelliSense 來幫助我們來選擇可以使用那些函式。
    多載 Overloading
    這是在建置時間就會決定的。
  • 覆寫 Overriding
    在類別繼承關係中,在基底類別與衍生類別中,都會使用到相同函式簽章的函式,因此,在執行時期,需要明確指出要使用基底類別或者衍生類別的哪個函式來執行。
    這是在執行時期才會決定的

多載 Overloading

首先我們先來看看 多載 Overloading 的使用與運作情況,在底下我們建立了一個類別,在這個類別中,有兩個同名的函式,都是命名為 Hello。
不過,這兩個同名的函式,卻宣告使用不同的參數數量與類型,因此,這裡將會套用到多載這樣的觀念。
public class MyClass
{
    public void Hello()
    {
        Console.WriteLine("Who are you");
    }
    public void Hello(string name)
    {
        Console.WriteLine($"Hello {name}");
    }
}
現在,讓我們來實際使用這個 Hello 方法,從底下的測試程式碼中,我們將會呼叫兩個不同的 Hello 函式,並且可以從輸出結果內容中,得到驗證,確實多載方法有被呼叫到。
Console.WriteLine($"多載 Overloading 的使用");
MyClass myClass = new MyClass();
myClass.Hello();
myClass.Hello("Vulcan");
Console.WriteLine($"Press any key for continuing...{Environment.NewLine}");
Console.ReadKey();
這是執行結果的輸出內容
多載 Overloading 的使用
Who are you
Hello Vulcan
Press any key for continuing...

覆寫 Overriding

接下來,我們來看看覆寫 Overriding如何使用。
我們先建立兩個類別,一個是基底類別 MyBaseClass,另外一個是繼承前面基底類別而產生的衍生類別 MyDerivedClass。在這兩個類別,都宣告了同樣函式簽章的方法,只不過,在基底類別的 Hello 方法前面,有使用 virtual (這表示可用來修改方法、屬性、索引子或事件宣告,並可在衍生類別中受到覆寫),並且,我們也在衍生類別的 Hello 方法前面使用了 override (能夠擴充或修改繼承方法、屬性、索引子或事件的抽象或虛擬實作)。
public class MyBaseClass
{
    public virtual void Hello()
    {
        Console.WriteLine("Hello MyBaseClass");
    }
}

public class MyDerivedClass : MyBaseClass
{
    public override void Hello()
    {
        Console.WriteLine("Hello MyDerivedClass");
    }
}
我們在這裡建立三個物件,前兩的物件的宣告型別與實際產生物件的型別都是一致的,因此,我們可以知道他們所需要的 Hello 方法,就是當時所宣告與產生物件型別的定義方法。
不過,對於第三個物件 myDerivedBaseClass,我們使用底下說明的內容建立起來
  • 物件的型別為 MyBaseClass
    MyBaseClass myDerivedBaseClass
  • 產生物件的型別為 MyDerivedClass
    new MyDerivedClass()
因此,當要執行這個 myDerivedBaseClass.Hello(); 函式執行的時候,在執行時期,CLR 會檢查當時的物件宣告型別,若該宣告型別的函示沒有被覆蓋過,則就會直接執行當時宣告該物件型別內定義的方法;然而,若在實際建立起來的物件型別內,有覆蓋這個方法定義,則此時就會呼叫被覆蓋的方法。
在這個練習範例中,物件的宣告型別為 MyBaseClass,實際產生的物件型別為 MyDerivedClass,因為這個衍生類別的 Hello 方法,有使用 override 覆寫方法定義,所以,在實際執行的時候,不論宣告的型別是基底或者衍生類別,都會直接執行衍生類別中的 Hello 方法。
各位可以嘗試看看,若將基底類別的 virtual 與衍生類別的 override 關鍵字刪除掉,再度執行同樣的測試程式碼,會產生甚麼樣的狀況嗎?
Console.WriteLine($"覆寫 Overriding 的使用");
MyBaseClass myBaseClass = new MyBaseClass();
MyDerivedClass myDerivedClass = new MyDerivedClass();
MyBaseClass myDerivedBaseClass = new MyDerivedClass();
myBaseClass.Hello();
myDerivedClass.Hello();
myDerivedBaseClass.Hello();
Console.WriteLine($"Press any key for continuing...{Environment.NewLine}");
Console.ReadKey();
這是執行結果的輸出內容
覆寫 Overriding 的使用
Hello MyBaseClass
Hello MyDerivedClass
Hello MyDerivedClass
Press any key for continuing...

了解更多關於 [成員多載的使用方式
了解更多關於 [override (C# 參考)的使用方式
了解更多關於 [C# 程式設計手冊]






1 則留言: