偶然间看到的题,借此记录。

 class Program{static void Main(string[] args){D d = new D();  //第一个D是申明类,第二个D是实例类A a = d;B b = d;C c = d;a.F();b.F();c.F();d.F();}class A{public virtual void F() { Console.WriteLine("A.F"); }}class B : A{public override void F() { Console.WriteLine("B.F"); }}class C : B{public virtual void F() { Console.WriteLine("C.F"); }}class D : C{public override void F() { Console.WriteLine("D.F"); }}}

输出结果:

下面记录一下解题步骤:

a.F();  >>>  1. 检查申明类A 2. 是虚方法 3. 继续检查实例类D 4. 有重写,但是相对于类A来说Fun()在类C中被new 过,根据口诀“new则看类型,override只管新” 5. 继续检查父类B 6. 类B中override了父类A的 Fun() 7. 执行类B中的Fun(),输出B.F

b.F();  >>>  1. 检查申明类B 2. 不是虚方法 3. 直接执行类B中的Fun(),输出B.F

c.F();  >>>  1. 检查申明类C 2. 是虚方法 3. 继续检查实例类D 4. 有重写,类D重写了类C中的Fun(),根据口诀“new则看类型,override只管新” 5. 执行类D中的Fun(),输出D.F

d.F();  >>>  1. 检查申明类D 2. 不是虚方法 3. 直接执行类D中的Fun(),输出D.F

摘用一下别人特别好的总结:

具体的检查的流程如下

1、当调用一个对象的函数时,系统会直接去检查这个对象申明定义的类,即申明类,看所调用的函数是否为虚函数;

2、如果不是虚函数,那么它就直接执行该函数。而如果有virtual关键字,也就是一个虚函数,那么这个时候它就不会立刻执行该函数了,而是转去检查对象的实例类。

3、在这个实例类里,他会检查这个实例类的定义中是否有重新实现该虚函数(通过override关键字),如果是有,那么OK,它就不会再找了,而马上执行该实例类中的这个重新实现的函数。而如果没有的话,系统就会不停地往上找实例类的父类,并对父类重复刚才在实例类里的检查,直到找到第一个重载了该虚函数的父类为止,然后执行该父类里重载后的函数。

在上面的规则中,可以看到,如果子类没有override的修饰,那么就算父类是virtual的方法,子类的方法也无法被调用,而会去它的父类中找override的方法,直到找到祖先类。所以在面向对象的开发过程中,如果要实现Dependency Injection、IoC等设计模式,就必须非常留意类设计中继承方法的声明,否则很可能导致实际的程序运行与预期不符。

引用:https://www.cnblogs.com/yanyao/p/4830768.html

转载于:https://www.cnblogs.com/ZCrystal/p/11008409.html

virtual和override相关推荐

  1. C# 虚方法(virtual)覆盖(override) - 隐藏(new) - 重载

    C# 虚方法(virtual)覆盖(override) - 隐藏(new) - 重载 using System; using System.Collections.Generic; using Sys ...

  2. abstract、virtual、override 和 new

     abstract.virtual.override 和 new 是在类的继承关系中常用的四个修饰方法的关键字,在此略作总结. 1. 常用的中文名:abstract 抽象方法,virtual 虚方法, ...

  3. virtual和override作用和使用场景及理解

    virtual和override 作用和使用场景及理解 以下理解: 是父类给出一个带默认值的属性或方法.子类有很大的重写可能性,但又不一定会重写. 不就是重写方法吗 类的三个特性 封装 继承  多态 ...

  4. C#.NET 虚方法中中的virtual 和override关键字的使用

    谈到C#.NET的虚方法就不得不先说一下继承性(inheritance),继承和多态度.封装一起构成面向对象程序设计的三大要素,继承指一个类基于一个已有的类按照需求添加和删除一些功能. 首先,我们通过 ...

  5. C#的static,interface,virtual,abstract,override的区别用法

    C# 是面向对象的程序设计语言,每一个函数都属于一个类. Static:当一个方法被声明为Static时,这个方法是一个静态方法,编译器会在编译时保留这个方法的实现.也就是说,这个方法属于类,但是不属 ...

  6. C# 关键字 virtual、override和new的用法

    代码如下: class A {public void foo(){Console.WriteLine("A::foo()");}public virtual void bar(){ ...

  7. C#中的static,interface,virtual,abstract,override的用法

    C# 是面向对象的程序设计语言,每一个函数都属于一个类. Static:当一个方法被声明为Static时,这个方法是一个静态方法,编译器会在编译时保留这个方法的实现. 也就是说,这个方法属于类,但是不 ...

  8. C#--virtual,abstract,override,new,sealed修饰符学习

    1.参考博客  http://www.cnblogs.com/oneword/archive/2009/07/02/1515279.html http://www.cnblogs.com/mygood ...

  9. C++:44---关键字virtual、override、final

    一.虚函数 概念:在函数前面加virtual,就是虚函数 虚函数的一些概念: 只有成员函数才可定义为虚函数,友元/全局/static/构造函数都不可以 虚函数需要在函数名前加上关键字virtual 成 ...

最新文章

  1. Java实现无向图的邻接列表表示,深度遍历及广度遍历
  2. 【杂谈】从医学专业转行到AI,独立完成项目到获得加州理工大学读研推荐,我如何与有三AI结缘...
  3. Silverlight如何与JS相互调用
  4. java 范围搜寻要怎么弄_搜索范围
  5. 使用js实现换肤功能
  6. java语言50到100之间素数和_用JAVA语言编写一程序,求100以内的所有素数
  7. Linux中的文件被异常删除的排查思路
  8. python产生随机数_python技能:random库的使用
  9. 证券公司财务帐单分析报告自动生成系统
  10. JAVA校园二手交易平台
  11. CCF 区块链国际会议 统计 有哪些接收区块链论文的会议 (最全)
  12. 如何在vue 中使用组件,以及组件通信的方式(父传子/子传父/兄弟传)
  13. 黑苹果音频卡顿_手机耗电大、卡顿怎么办?只需关掉这个按键轻松解决,去试试...
  14. Virtual ChIP-seq: predicting transcription factor binding by learning from the transcriptome
  15. git教程(涵盖GitHub\Gitee\Gitlab)
  16. 分类模型-评估指标(2):ROC曲线、 AUC值(ROC曲线下的面积)【只能用于二分类模型的评价】【不受类别数量不平衡的影响;不受阈值取值的影响】【AUC的计算方式:统计所有正负样本对中的正序对】
  17. 2018年10月移动应用APP活跃用户数排行榜TOP20
  18. Chosen by god【组合数打表】
  19. 计算机桌面上无网络图标,电脑的网络图标消失了怎么恢复?
  20. HID蓝牙遥控器 - 支持键盘、鼠标、影音遥控器(开源)

热门文章

  1. MVC学习笔记1 MVC概述
  2. ASP.NET 中处理页面“回退”的方法
  3. 服务器能否只做c盘系统,我的云服务器只有一个c盘
  4. plsql 为空显示 0 的函数_不加班只加薪!从0到1教你制作出入库进销存表格
  5. php上传文件 服务器内部错误,php – 在将图像上传到S3时遇到内部服务器错误500...
  6. python输入一个数组输出24进制式的时间_4.4 用于数组的文件输入输出 线性代数...
  7. navision系统和sap区别_SAP那些事-实战篇-89-浅谈金税接口方案
  8. android签到功能模块,基于android的课堂签到系统.doc
  9. Redis的RDB文件与AOF文件
  10. leetcode 69. x 的平方根 思考分析