多態
多態是物件導向的第三大特性。多態表示不同的對象可以執行相同的動作,但要通過他們自己的實現代碼來執行。舉例說明:國粹京劇以前都是子承父業,代代相傳的藝術,假設有一對父子,父親是非常出名的京劇藝術家,兒子也已長大成人,且模仿父親的戲惟妙惟肖。有一天父親病了,不能登台演出,而票早就賣出,退票是會嚴重影響聲譽。怎麼辦呢?由於京劇是化妝後表演,於是最好的辦法就是由兒子待父親上台表演。
這裡面有幾點注意:第一,子類以父類的身份出現。兒子代表老子表演,化妝後就是一父親的身份出現了。第二 ,子類在工作中以自己的方式來實現。兒子模仿的再好,兒子也只能以自己理解的表現方式去模仿父親的表演。第三,子類以父類的身份出現時,子類特有的屬性和方法不可以使用。兒子通過多年的學習,其實早已有了自己的東西。但在此時,代表父親表演,絕對是不能表現出來的。這就是多態。
虛方法:為了使子類的執行個體完全接替來自父類的類成員,父類必須將該成員聲明為虛擬。這是通過再改成員的傳回型別前加virtual關鍵詞來實現。通常虛擬是方法。其實除了欄位不能是虛擬外,屬性、事件、和索引器都可以是虛擬。儘管方法可以是虛擬,但虛方法還是有方法體,可以實際做些事。子類可以選擇使用override關鍵字,將父類實現替換為他自己的實現,這就是方法重寫Override,或叫做方法覆寫。
動物基類:
/// <summary>
///父類
/// </summary>
public class Animal
{
protected string name = "";
protected int shoutNum = 3;
public Animal(string name)
{
this.name = name;
}
public Animal()
{
this.name = "無名";
}
/// <summary>
/// 虛方法
/// </summary>
/// <returns></returns>
public virtual string Shout()
{
return "";
}
}
貓子類:
/// <summary>
/// Cat子類
/// </summary>
public class Cat:Animal
{
public Cat()
: base()
{ }
public Cat(string name)
: base(name)
{ }
public override string Shout()
{
string result = "";
for (int i = 0; i < shoutNum; i++)
{
result = result + "嘧,";
}
return "我的名字叫" + name + " " + result;
}
}
狗子類: /// <summary>
/// Dog子類
/// </summary>
public class Dog : Animal
{
public Dog()
: base()
{ }
public Dog(string name)
: base(name)
{ }
public override string Shout()
{
string result = "";
for (int i = 0; i < shoutNum; i++)
{
result = result + "汪,";
}
return "我的名字叫" + name + " " + result;
}
}
動物叫聲大賽: public class Match
{
private Animal[] arrAnimal;
private string ShoutMatch()
{
string Result = "";
arrAnimal = new Animal[2];
arrAnimal[0] = new Cat("小花");
arrAnimal[1] = new Dog("阿毛");
foreach (Animal item in arrAnimal)
{
Result = Result + item.Shout()+";";
}
return Result;
}
}
Animal相當於京劇的父親,Cat和Dog相當於兒子,兒子代表父親表演Shout,但是Cat叫出來的嘧,Dog叫出來的汪。這就是不同的對象可以執行相同的動作,但要通過他們自己的實現代碼來執行。
注意:對象的聲明必須是父類,而不是子類,執行個體化的對象是子類。
多態的原理是當方法被調用時,無論對象是否被轉化為其父類,都只有位於對象繼承鏈最末端的方法實現會被調用。也就是說,虛方法是按照其運行時類型而非編譯時間類型進行動態綁定調用。