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 是真的实参的,即使声明是父类,但是子类改写了,父类调用是还是用了子类的函数。

时间: 2024-12-15 17:07:36

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

JavaSE 类继承中函数重写

(1) /** * 继承时重写方法的返回类型可以不一样 * 这时的返回值类型必须是与父类相同或者为子类. */ class A { public Object func(){ return null; } } class B extends A { public String func() { return null; } } (2) /** * 重写的方法的访问权限要大于或等于原方法 */ class A { protected String func(){ return null; } }

UML类图关系(泛化 、继承、实现、依赖、关联、聚合、组合)

http://www.cnblogs.com/olvo/archive/2012/05/03/2481014.html http://sundensky.blog.163.com/blog/static/7728873420109299167434/ 继承.实现.依赖.关联.聚合.组合的联系与区别 分别介绍这几种关系: 继承 指的是一个类(称为子类.子接口)继承另外的一个类(称为父类.父接口)的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间最常见的关系:在Java中此类关系

【UML】UML类图关系(泛化 、继承、实现、依赖、关联、聚合、组合)

http://www.cnblogs.com/olvo/archive/2012/05/03/2481014.html 继承.实现.依赖.关联.聚合.组合的联系与区别 分别介绍这几种关系: 继承 指的是一个类(称为子类.子接口)继承另外的一个类(称为父类.父接口)的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间最常见的关系:在Java中此类关系通过关键字extends明确标识,在设计时一般没有争议性:  实现 指的是一个class类实现interface接口(可以是多个)的

[tty与uart]1.Linux中tty框架与uart框架之间的调用关系剖析

转自:http://developer.51cto.com/art/201209/357501_all.htm 目录 在这期间有一个问题困扰着我,那就是来自用户空间的针对uart设备的操作意图是如何通过tty框架逐层调用到uart层的core驱动,进而又是如何调用到真实对应于设备的设备驱动的,本文中的对应设备驱动就是8250驱动,最近我想将这方面的内容搞清楚. 在说明这一方面问题之前我们先要大致了解两个基本的框架结构,tty框架和uart框架. 1.tty框架 在linux系统中,tty表示各种

UML类图关系表示方法

本文转载: http://blog.csdn.net/fengsh998/article/details/8105631 分类: UML2012-10-24 10:18 1175人阅读 评论(0) 收藏 举报 UML类图关系的表示方法,主要包括关联,聚合,泛化,实现,依赖等内容,希望通过本节的学习大家对UML类图关系的表示方法有一定的掌握.下面是具体介绍. UML基础 1:UML类间关系的种类 2:关联 UML类图关系中关联描述了系统中对象或实例之间的离散连接,关联带有系统中各个对象之间关系的信

Linux中tty框架与uart框架之间的调用关系剖析【转】

转自:http://developer.51cto.com/art/201209/357501.htm 之前本人在"从串口驱动的移植看linux2.6内核中的驱动模型 platform device & platform driver"一文中已经写到了移植的设备是如何通过platform总线来与对应的驱动挂载. 在这期间有一个问题困扰着我,那就是来自用户空间的针对uart设备的操作意图是如何通过tty框架逐层调用到uart层的core驱动,进而又是如何调用到真实对应于设备的设备

23.C++- 继承的多种方式、显示调用父类构造函数、父子之间的同名函数、virtual虚函数

在C++中,继承方式共有3种: public继承 -指父类的成员(变量和函数)访问级别,在子类中保持不变 private继承 -指父类的成员,在子类中变为private私有成员. -也就是说子类无法访问父类的所有成员 protected继承 -指父类的public成员 ,在子类中变为protected保护成员,其它成员级别保持不变 <span "="" src="https://images2018.cnblogs.com/blog/1182576/20180

处理菱形继承问题&&实现一个虚函数的覆盖及调用&&实现以下几个类的成员函数

#include <iostream> #include <string> using namespace std; 1.实现以下几个类的成员函数 2.实现一个虚函数的覆盖及调用 3.处理菱形继承问题. 植物 class Botany { public: //(const string& name) // const char* name Botany(const char* name = "") :_name(name) //构造函数 { //cout

父子类之间,成员函数重写、重载以及重定义的区别

1.重写override:也叫做覆盖.子类重新定义父类中有相同名称和参数列表的虚函数.函数特征相同. 重写需要注意: 1) 被重写的函数不能是static的.必须是virtual的 2) 重写函数必须有相同的类型,名称和参数列表 3) 重写函数的访问修饰符可以不同.尽管virtual是private的,派生类中重写改写为public,protected也是可以的 2.重载overload:是函数名相同,参数列表等特征不同.但是不能靠返回类型来判断. 3.重定义redefining也叫做隐藏: 子