首页 > 代码库 > C# 继承后 函数重写父子类调用关系的逻辑

C# 继承后 函数重写父子类调用关系的逻辑

首先吐槽一下自己,做完实验之后,居然忘记到底是什么原因导致想搞清楚这个东西了。有点本末倒置。

首先一点,两种重写函数语法上的差异。

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 = http://www.mamicode.com/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# 继承后 函数重写父子类调用关系的逻辑