摘要:[C#]多型(Polymorphism)-一個簡單的範例
多型這個概念在網路上有許多文章解釋得很好-如:搞笑談軟工-Polymorphism。我自己理解的多型比較偏向實作面的解釋方式
當子類別的物件宣告或轉型成父類別 或祖先類別 的型別時,還可以正確執行該子類別的行為。
以一個Example來說,延續C#繼承的例子,Class定義及Client端程式如下:
using System;
public class Program
{
public static void Main()
{
Parent cObj = new Child();
cObj.Name = "ccc";
cObj.Print();
}
}
public class Parent
{
public string Name { get; set; }
public void Print()
{
Console.WriteLine("Parent Name: " + this.Name );
}
}
public class Child : Parent
{
new public void Print()
{
Console.WriteLine("Child Name: " + this.Name );
}
}
以Client端的程式碼來說Parent cObj = new Child();
,這是表示建立了一個子類別-Child的物件,但是宣告為父類別-Parent的型別。如果呼叫該物件的Print()
,可以顯示出子類別Print()
的訊息 - Child Name: ccc
,而不是父類別Print()
的訊息- Parent Name: ccc
,就表示做到多型的效果了。
只是目前的程式碼無法達到這個效果。
virtual & override
要做到這一點,就需要在父類別的method加上virtual
或abstract
關鍵字。這表示叫用該method時,編譯器必須檢視物件實際的型別,而不能只檢視參址器的型別。
public class Parent
{
public string Name { get; set; }
public virtual void Print()
{
Console.WriteLine("Parent Name: " + this.Name );
}
}
另外,子類別的同名method上,也必須加上override
關鍵字。這代表子類別知道父類別有一個同名的method,且要用子類別的實作覆蓋父類別的實作。
public class Child : Parent
{
override public void Print()
{
Console.WriteLine("Child Name: " + this.Name );
}
}
Client端程式碼如下:
public class Program
{
public static void Main()
{
Parent pObj = new Parent();
pObj.Name = "papa";
TestPolymorphism(pObj);
Child cObj = new Child();
cObj.Name = "ccc";
TestPolymorphism(cObj);
}
static void TestPolymorphism(Parent parentObj)
{
parentObj.Print();
}
}
可以看到,我們建立了Parent跟Child類別的兩個物件: pObj
以及 cObj
。然後使用TestPolymorphism(Parent parentObj)
method呼叫Print()
。執行的結果,已經會依據實際的類別叫用其method的實作。
Parent Name: papa
Child Name: ccc
整個程式碼列出如下
using System;
public class Program
{
public static void Main()
{
Parent pObj = new Parent();
pObj.Name = "papa";
TestPolymorphism(pObj);
Child cObj = new Child();
cObj.Name = "ccc";
TestPolymorphism(cObj);
}
static void TestPolymorphism(Parent parentObj)
{
parentObj.Print();
}
}
public class Parent
{
public string Name { get; set; }
public virtual void Print()
{
Console.WriteLine("Parent Name: " + this.Name );
}
}
public class Child : Parent
{
override public void Print()
{
Console.WriteLine("Child Name: " + this.Name );
}
}