標籤:
首先吐槽一下自己,做完實驗之後,居然忘記到底是什麼原因導致想搞清楚這個東西了。有點本末倒置。
首先一點,兩種重寫函數文法上的差異。
new 是不看父類怎麼寫的,直接就寫了。Override 是要父類聲明 abstract virtual 之類可以重寫的標籤才能重寫。
首先看看父類的結構
using System;namespace HixLearnCSharp{ /// <summary> /// 爸爸類 /// </summary> class ParentClass { /// <summary> /// 聲明委託及委託執行個體 /// </summary> public delegate void Show(); public Show ShowFunc; protected int innerValue; //內部值 public ParentClass() { Console.WriteLine("Parent had Create!"); innerValue = 1; ///在父類中 值為1; } /// <summary> /// 不會重寫的方法 /// </summary> public void UnReLoadFunc() { Console.WriteLine("InUnReLoadFunc innerValue is {0} !", innerValue); } /// <summary> /// 將會被New重寫的方法 /// </summary> public void WillBeNewFunc() { Console.WriteLine("Parent‘s WillBeNewFunc is {0} !", 2); } /// <summary> /// 將會被Override 重寫的方法 /// </summary> public virtual void WillBeOverriveFunc() { Console.WriteLine("Parent‘s WillBeOverriveFunc is {0} !", 3); } /// <summary> /// 內部調用測試方法 /// </summary> public void FuncTset() { Console.WriteLine("parent‘s FuncTset"); WillBeNewFunc(); WillBeOverriveFunc(); Console.WriteLine("Test Over"); } /// <summary> /// 在委託中調用 /// </summary> public void delegateFuncTset() { Console.WriteLine("parent‘s delegateFuncTset"); ShowFunc += UnReLoadFunc; ShowFunc += WillBeNewFunc; ShowFunc += WillBeOverriveFunc; ShowFunc(); Console.WriteLine("Test Over"); } }}
再看看子類的結構
using System;namespace HixLearnCSharp{ /// <summary> /// Change的子類 /// </summary> class ChildClas : ParentClass { public ChildClas() { Console.WriteLine("child had Create!"); innerValue = 100; ///內部值被明顯的改寫了 } /// <summary> /// new改寫的方法 /// </summary> public new void WillBeNewFunc() { Console.WriteLine("InChild, WillBeNewFunc is {0} !", 200); } /// <summary> /// override改寫的方法 /// </summary> public override void WillBeOverriveFunc() { Console.WriteLine("InChild, WillBeOverriveFunc is {0} !", 300); } /// <summary> /// 直接內部調用 /// </summary> public void childValueTset() { Console.WriteLine("Child FuncTset"); base.WillBeNewFunc(); //顯式調用父類 WillBeNewFunc(); base.WillBeOverriveFunc(); WillBeOverriveFunc(); Console.WriteLine("Test Over"); } /// <summary> /// 在委託中調用 /// </summary> public void childdelegateValueTset() { Console.WriteLine("Child delegateFuncTset"); //為了更大改變 在被調用過的基礎上再改變值 innerValue = 1000; ShowFunc += UnReLoadFunc; ShowFunc += WillBeNewFunc; ShowFunc += WillBeOverriveFunc; ShowFunc(); Console.WriteLine("Test Over"); } }}
這是我的測試,結果有
using System;namespace HixLearnCSharp{ class Program { static void Main(string[] args) { //開始實驗 //先看看父類的原始情況 Console.WriteLine("parent test"); var p = new ParentClass(); //輸出原來的樣子 p.UnReLoadFunc(); p.FuncTset(); p.delegateFuncTset(); Console.WriteLine(""); //先看看 聲明是子類,實現是子類的情況 Console.WriteLine("child1 test"); ChildClas c1 = new ChildClas(); c1.UnReLoadFunc(); //輸出的值已經變化了 Console.WriteLine("child1 Inner Func test"); c1.FuncTset(); // 很明顯 New 的還是調用了父類 方法 ,Override 就是調用了子類的方法 c1.delegateFuncTset(); //結果同上 c1.childValueTset(); // 除非顯示聲明要用父類的方法,否則都是用了子類的方法 c1.childdelegateValueTset(); // 可以看見 在委託中 真的是儲存了方法的指標,內部值的改變,行為也改變了。 Console.WriteLine("child1 Public Func test"); c1.WillBeNewFunc(); // 用了子類的方法 c1.WillBeOverriveFunc(); // 用了子類的方法 Console.WriteLine(""); //再看看 聲明是父類,實現是子類的情況 Console.WriteLine("child2 test"); ParentClass c2 = new ChildClas(); c2.UnReLoadFunc(); // 結果同上 Console.WriteLine("child2 Inner Func test"); c2.FuncTset(); // Benew 的方法用了父類的 ,BeOverride 用了子類的 c2.delegateFuncTset();// 結果同上 Console.WriteLine("child2 Public Func test"); c2.WillBeNewFunc();// 用了父類的方法 c2.WillBeOverriveFunc();// 用了子類的方法 Console.WriteLine(""); Console.ReadKey(); } }}
好吧,實驗結果 : new 是針對形參的,聲明什麼就用什麼。 override 是真的實參的,即使聲明是父類,但是子類改寫了,父類調用是還是用了子類的函數。
C# 繼承後 函數重寫父子類調用關係的邏輯