首先吐槽一下自己,做完实验之后,居然忘记到底是什么原因导致想搞清楚这个东西了。有点本末倒置。
首先一点,两种重写函数语法上的差异。
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 是真的实参的,即使声明是父类,但是子类改写了,父类调用是还是用了子类的函数。