遮蔽與覆寫

摘要:遮蔽與覆寫

今天同事看深入淺出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用覆寫,就能正常運作。

 

如文章有錯誤,煩請告知,新人發帖請多包涵

 

創用 CC 授權條款