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 = 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# 继承后 函数重写父子类调用关系的逻辑

上一篇:C#操作Xml:XPath语法 在C#中使用XPath示例


下一篇:c# 使用hook来监控鼠标键盘事件的示例代码