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

 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

virtual和override的更多相关文章

  1. [C#] 區分 abstract、virtual、override 和 new

    abstract.virtual.override和new是在類別的繼承關係中常用的四個修飾方法的關鍵字,在此略作總結. 1. 常用的中文名稱: n   abstract => 抽象方法. n  ...

  2. c#和java中的方法覆盖——virtual、override、new

    多态和覆盖 多态是面向对象编程中最为重要的概念之一,而覆盖又是体现多态最重要的方面.对于像c#和java这样的面向对象编程的语言来说,实现了在编译时只检查接口是否具备,而不需关心最终的实现,即最终的实 ...

  3. C#Virtual和Override的几种组合

    情况1: class A{public void Show()} class B:A{public void Show()} 编译通过,有警告让在B的方法里添加new关键字,以便将A的方法隐藏 编译时 ...

  4. new、virtual、override

    我们先看下面一段程序: public class Father { public void Run0() { Console.WriteLine("Father.Run0"); } ...

  5. C# virtual和override

    本文转载来自于:http://bollaxu.iteye.com/blog/1662855 在函数的声明中,当有“virtual”修饰的时候,和没有virtual有什么区别呢?最重要的一点就是调用实例 ...

  6. C#多态;父类引用指向子类对象;new和override的区别;new、abstract、virtual、override,sealed关键字区别和使用代码示例;c#类的初始化顺序

    关于父类引用指向子类对象 例如: 有以下2个类 public class Father { public int age = 70; public static string name = " ...

  7. C#--virtual,abstract,override,new,sealed

    virtual:使用此关键字,可以使其在派生类中被重写. abstract:抽象方法,由子类重写,或继续为抽象方法存在,并由其子子类实现. override: 重写父类方法,属性,或事件的抽象实现或虚 ...

  8. c#中关于virtual,override和new的理解

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...

  9. C#中的Virtual、Override和new关键词理解

    来源:http://blog.csdn.net/jackiezhw/article/details/2673992 在 C# 中,派生类可以包含与基类方法同名的方法. 基类方法必须定义为 virtua ...

  10. Asp.Net中virtual、override理解

    virtual关键字用于指定属性或方法在派生类中重写.默认情况下,派生类从其基类继承属性和方法,如果继承的属性或方法需要在派生类中有不同的行为,则可以重写它,即可以在派生类中定义该属性或方法的新实现, ...

随机推荐

  1. Jetson TX2介绍

    Jetson TX2是NIVDIA瞄准人工智能在Jetson TK1和TX1推出后的升级 TX2的GPU和CPU都进行了升级,内存增加到了8GB.存储增加到了32GB,支持Wifi和蓝牙,编解码支持H ...

  2. 007-log-log4j2、slf4j+log4j2

    一.概述 而log4j2的性能无论在同步日志模式还是异步日志模式下都是最佳的. 根本原因在于log4j2使用了LMAX, 一个无锁的线程间通信库代替了, logback和log4j之前的队列. 并发性 ...

  3. jmeter测试报告套路

    各位: 以下是本周第一次双师压测结果,后续优化后会更新优化结果.   配置: 压测环境:   staging压测服务器配置4核16G,数据库4核8G 线上环境:   服务器配置16核24G,数据库主库 ...

  4. spring常用模式--委派模式

    1.委派模式简介 在常用的23种设计模式中其实面没有委派模式(delegate)的影子,但是在Spring中委派模式确实用的比较多的一种模式. 在spring中的体现:Spring MVC框架中的Di ...

  5. pyCharm最新2017激活

    pyCharm最新2017:下载地址 下载完成后安装软件 启动pyCharm,进入下面窗口 选择License server 在 server选项里边输入 http://elporfirio.com: ...

  6. JavaScript 异步和单线程

    JavaScript语言本身是单线程的,所以它自身不可能是异步.所谓单线程,就必然意味着:所有任务需要排队,前一个任务结束,才会执行后一个任务. 但js的宿主环境(比如浏览器,Node)是多线程的.宿 ...

  7. CentOS下Hadoop及ZooKeeper环境搭建

    1. 测试环境 操作系统 CentOS 6.5. 总共5台机器,前两台作为namenode,称之为 nn01.nn02:后三台作为datanode,称为 dn01.dn02.dn03. 每台机器的内存 ...

  8. springboot-springmvc-requestParam

    springmvc请求方式 1.直接写在形参中:基本类型 @RequestMapping("/testRequestParam1") public ModelAndView tes ...

  9. Mac下Unity使用Jenkins自动化打包

    重要的事情说三遍:不要使用jenkins dmg安装包直接安装,用brew安装  PS:会有权限问题 重要的事情说三遍:不要使用jenkins dmg安装包直接安装,用brew安装 重要的事情说三遍: ...

  10. QFramework 使用指南 2020(九):Res Kit(3)异步加载 与 异步队列加载

    在上一篇我们了解了 Res Kit 的一些背后设计原理,讲解了一些概念,比如:开发阶段.真机阶段等. 在这一篇,我们回到 Res Kit 使用细节上. 在 Res Kit 的第一篇,我们介绍了 Res ...