virtual和override
偶然间看到的题,借此记录。
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的更多相关文章
- [C#] 區分 abstract、virtual、override 和 new
abstract.virtual.override和new是在類別的繼承關係中常用的四個修飾方法的關鍵字,在此略作總結. 1. 常用的中文名稱: n abstract => 抽象方法. n ...
- c#和java中的方法覆盖——virtual、override、new
多态和覆盖 多态是面向对象编程中最为重要的概念之一,而覆盖又是体现多态最重要的方面.对于像c#和java这样的面向对象编程的语言来说,实现了在编译时只检查接口是否具备,而不需关心最终的实现,即最终的实 ...
- C#Virtual和Override的几种组合
情况1: class A{public void Show()} class B:A{public void Show()} 编译通过,有警告让在B的方法里添加new关键字,以便将A的方法隐藏 编译时 ...
- new、virtual、override
我们先看下面一段程序: public class Father { public void Run0() { Console.WriteLine("Father.Run0"); } ...
- C# virtual和override
本文转载来自于:http://bollaxu.iteye.com/blog/1662855 在函数的声明中,当有“virtual”修饰的时候,和没有virtual有什么区别呢?最重要的一点就是调用实例 ...
- C#多态;父类引用指向子类对象;new和override的区别;new、abstract、virtual、override,sealed关键字区别和使用代码示例;c#类的初始化顺序
关于父类引用指向子类对象 例如: 有以下2个类 public class Father { public int age = 70; public static string name = " ...
- C#--virtual,abstract,override,new,sealed
virtual:使用此关键字,可以使其在派生类中被重写. abstract:抽象方法,由子类重写,或继续为抽象方法存在,并由其子子类实现. override: 重写父类方法,属性,或事件的抽象实现或虚 ...
- c#中关于virtual,override和new的理解
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...
- C#中的Virtual、Override和new关键词理解
来源:http://blog.csdn.net/jackiezhw/article/details/2673992 在 C# 中,派生类可以包含与基类方法同名的方法. 基类方法必须定义为 virtua ...
- Asp.Net中virtual、override理解
virtual关键字用于指定属性或方法在派生类中重写.默认情况下,派生类从其基类继承属性和方法,如果继承的属性或方法需要在派生类中有不同的行为,则可以重写它,即可以在派生类中定义该属性或方法的新实现, ...
随机推荐
- java课后实验性问题2
课后作业一:计算组合数 程序设计思想: 从键盘获取组合数,判断是否构成组合数.分别用三种方法计算组合数输出. 程序流程图: import java.util.Scanner; public class ...
- 详解Intellij IDEA中.properties文件中文显示乱码问题的解决
首先,你可能会见到如下提示: File encoding is disabled because .properties file (see Settings|Editor|File Encoding ...
- Jquery.Data()和HTML标签的data-*属性
Jquery.Data()和HTML标签的data-*属性 一.总结 一句话总结: 在页面中用到要用标签存数据还是用HTML标签的data-*属性,这样 不会破坏html本身的结构 1.使用HTML标 ...
- 文件转移 互联网组成 路由器 分组交换 交换机 冲突域 网卡 数据帧的发送与接收会带来CPU开销 CPU中断 双网卡切换
https://zh.wikipedia.org/zh-cn/网段 在以太网环境中,一个网段其实也就是一个冲突域(碰撞域).同一网段中的设备共享(包括通过集线器等设备中转连接)同一物理总线,在这一总线 ...
- SQL-W3School-高级:SQL Date 函数
ylbtech-SQL-W3School-高级:SQL Date 函数 1.返回顶部 1. SQL 日期 当我们处理日期时,最难的任务恐怕是确保所插入的日期的格式,与数据库中日期列的格式相匹配. 只要 ...
- Kinect关节数据
3 -0.118269 0.655295 1.7431 930.03 139.5962 -0.124249 0.506111 1.79473 926.387 239.42820 -0.122777 0 ...
- Go 微服务架构Micro相关概念理解
Micro是一个微服务框架(或者说是工具集):提供了各类组件,解决微服务架构中的不同问题,服务监控.服务发现.熔断机制,负载均衡等等,自己一个个解决这些问题几乎不可能,这时候就需要借助go-micro ...
- 消息队列之ActiveMQ学习笔记(二、C#实例实现)
ActiveMQ提供多种语言支持,如Java, C, C++, C#, Ruby, Perl, Python, PHP等.此处列举C#实例 下述C#实例代是基于QUEUE的P2P方式,如需要实现TOP ...
- RegexBuddy 4.7.0 x64 评估试用到期,无限试用的办法
http://www.cnblogs.com/inrg/p/6491043.html 最后对比发现,在注册表 HKEY_USERS 节点下存在一个用户的项,形如 "S-1-5-21-1609 ...
- python遍历文件夹中所有文件夹和文件,os.walk
python中可以用os.walk来遍历某个文件夹中所有文件夹和文件. 例1: import os filePath = 'C:/Users/admin/Desktop/img' for dirpat ...