來個物件繼承觀念及C#語法小考,試著用大腦編譯及執行以下程式,並預測執行結果:

using System;
 
class Program
{
    static void Main(string[] args)
    {
        ChildClass c = new ChildClass();
        ParentClass p = c as ParentClass;
        Console.WriteLine("===ChildClass===");
        c.MethodA(); c.MethodB(); c.MethodC();
        Console.WriteLine("===ChildClass as ParentClass===");
        p.MethodA(); p.MethodB(); p.MethodC();
        Console.Read();
    }
}
 
class ParentClass
{
    public virtual void MethodA()
    {
        Console.WriteLine("ParentClass.MethodA");
    }
    public void MethodB()
    {
        Console.WriteLine("ParentClass.MethodB");
    }
    public void MethodC()
    {
        Console.WriteLine("ParentClass.MethodC");
        MethodA(); MethodB();
    }
}
class ChildClass : ParentClass
{
    public override void MethodA()
    {
        Console.WriteLine("ChildClass.MethodA");
    }
    public void MethodB()
    {
        Console.WriteLine("ChildClass.MethodB");
    }
}

以上的程式碼目的在示範virtual與否的區別,實際執行結果如下,你答對了嗎?

===ChildClass===
ChildClass.MethodA
ChildClass.MethodB
ParentClass.MethodC
ChildClass.MethodA
ParentClass.MethodB
===ChildClass as ParentClass===
ChildClass.MethodA
ParentClass.MethodB
ParentClass.MethodC
ChildClass.MethodA
ParentClass.MethodB

在程式碼中MethodA被宣告成virtual,所以不管是ChildClass或轉型成ParentClass、或是在ParentClass的MethodC裡被呼叫,都會以ChildClass override過的版本為準。而MethodB因為沒有宣告virtual/override,等同於ChildClass及ParentClass裡各有自己的版本,在轉型成ParentClass後再呼叫,執行的就是ParentClass的版本;而宣告在ParentClass的MethodC中所引用的,也永遠以ParentClass的版本為準。

實際上,這段程式在編輯時,Visual Studio會苦勸你回頭是岸(源於Compiler提出的警告),ChildClass裡應宣告成public new void MethodB()較為妥當,代表此MethodB與父層物件並無繼承關係,純粹只是名稱相同。加new後,語意較明確,有助於他人(或自己在日後)對程式碼的理解。

Warning: 'ChildClass.MethodB()' hides inherited member 'ParentClass.MethodB()'. Use the new keyword if hiding was intended.

再追加一點,若把ChildClass MethodA前的override拿掉,也等同於宣告一個同名但無繼承關係的Method,跟加new效果相同,Visual Studio一樣會提出警告。

Warning 'ChildClass.MethodA()' hides inherited member 'ParentClass.MethodA()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword. 

【延伸閱讀】


Comments

Be the first to post a comment

Post a comment