摘要:遮蔽與覆寫
今天同事看深入淺出C#發現裡面有一段在講解遮蔽的段落似乎好像表達不是很好,因此讓他對於遮蔽有一些小問題,雖然我也看過,不過當時覺得遮蔽這種寫法不太好,容易在未來維護會讓自己鬼打牆,因此那個段落我瞄了一下就跳過了。
以下為我寫了一個小範例,有一個很好玩的地方,父類別沒有virtual,居然被子類別給遮蔽掉了,而且還編譯過了,記得我以前對繼承不熟悉時,不知道有virtual,還因此挨了一個悶虧,不過現在看來,好險當時的CODE沒這麼簡單,很容易就發現問題所在,不然就真的傻傻的繼續用這種錯誤的觀念寫CODE了,不過如果要用遮蔽,在方法前面加上new就可以遮蔽。
class Program
{
static void Main(string[] args)
{
//父親的名子
Father father = new Father();
father.ShowMyName();
//壞孩子出現毛毛蟲,但編譯過了,且運行正常,遮蔽了老爸
BadSon son = new BadSon();
son.ShowMyName();
//矯正過的孩子,遮蔽了父親
NewSon son2 = new NewSon();
son2.ShowMyName();
//詭異的兒子,居然把自己當成老爸了
Father son3 = new Son();
son3.ShowMyName();
//小聰明的兒子,以為用new遮蔽了爸爸,結果失敗了
Father son4 = new Sonny();
son4.ShowMyName();
//好兒子,終於用對方法,早該用覆寫了
Father goodSon = new GoodSon();
goodSon.ShowMyName();
}
}
class Father
{
private string myName = "David";
public virtual void ShowMyName()
{
string name = myName;
Console.WriteLine(string.Format("my name is {0}.", name));
}
}
class BadSon:Father
{
private string myName = "jack";
public void ShowMyName()
{
string name = myName;
Console.WriteLine(string.Format("my name is {0}.", name));
}
}
class NewSon : Father
{
private string myName = "tom";
new public void ShowMyName()
{
string name = myName;
Console.WriteLine(string.Format("my name is {0}.", name));
}
}
class Son : Father
{
private string myName = "hank";
public void ShowMyName()
{
string name = myName;
Console.WriteLine(string.Format("my name is {0}.", name));
}
}
class Sonny : Father
{
private string myName = "hank";
new public void ShowMyName()
{
string name = myName;
Console.WriteLine(string.Format("my name is {0}.", name));
}
}
class GoodSon : Father
{
private string myName = "hao";
public override void ShowMyName()
{
string name = myName;
Console.WriteLine(string.Format("my name is {0}.", name));
}
}
當使用子類別參考變數時,就被不肖子的新方法所遮蔽,但如果用父類別參考變數,就會還是呼叫父類別的方法,Sonny儘管用正確的方式多加了new在方法前面,依照深入淺出c#裡面的解釋,有點饒舌,Father son4 = new Sonny(); son4.ShowMyName();,儘管它是指向Sonny,並且Sonny遮蔽了ShowMyName(),但此時呼叫的還是Father裡面定義的ShowMyName(),因為Sonny只是遮蔽ShowMyName(),他自己的ShowMyName()也不會被呼叫(這句話我也看到出神,看不懂啊),但可以用前面那句話來解釋就好,此時呼叫的是父類別方法,看起來遮蔽跟覆蓋並不是相似的東西,在GoodSon用覆寫,就能正常運作。
如文章有錯誤,煩請告知,新人發帖請多包涵