C#中的虚函数virtual
简单介绍虚函数virtual
在某基类中声明 virtual 并在一个或多个派生类中被重新定义的成员函数称为虚函数。
虚函数的作用就是实现多态性(Polymorphism),多态性是将接口与实现进行分离。
C#作为完全面向对象语言,所有函数并不默认为virtual,但可以在基类中声明关键字virtual,就可以在其派生类中通过关键字override重写该函数。重写后的virtual函数依旧是virtual函数。由于virtual只对类中的实例函数成员有意义,所以成员字段和静态函数都不能声明为virtual,也不能与override和abstract一起用。
虚函数与一般函数的区别
一般函数在编译时就静态地编译到了执行文件中,其相对地址在程序运行期间是不发生变化的,也就是写死的!而虚函数在编译期间是不被静态编译的,它的相对地址是不确定的,它会根据运行时期对象实例来动态判断要调用的函数,其中声明时定义的类叫声明类,执行时实例化的类叫实例类。
使用虚函数virtual
1、当调用一个对象的函数时,系统会直接去检查这个对象声明定义的类,即声明类,看所调用的函数是否为虚函数。
2、如果不是虚函数,那么它就直接执行该函数。而如果有virtual关键字,也就是一个虚函数,那么这个时候它就不会立刻执行该函数了,而是转去检查对象的实例类。
3、在这个实例类里,他会检查这个实例类的定义中是否有重新实现该虚函数(通过override关键字),如果有,则马上执行该实例类中的这个重新实现的函数。而如果没有,系统会不停地往上找实例类的父类,并对父类重复刚才在实例类里的检查,直到找到第一个重载了该虚函数的父类为止,然后执行该父类里重载后的函数。
实例:

运行结果:

常见面试题:
class Program
{
class A
{
public A()
{
PrintFields();
}
public virtual void PrintFields() { }
} class B : A
{
int x = 1;
int y; public B()
{
y = -1;
} public override void PrintFields()
{
Console.WriteLine("x={0},y={1}", x, y);
}
} static void Main(string[] args)
{
new B();
}
}
问:当使用new B()创建B的实例时,产生什么输出?
答:x=1,y=0
解析:创建B的实例,先隐式调用父类A的无参构造函数,执行PrintFields()方法,检查到是虚方法,转去检查实例类B,有重载方法,执行重载方法,输出x=1,y=0
注意:创建子类对象时会首先调用父类的构造函数,然后才会调用子类本身的构造函数,如果没有指明要调用父类的哪一个构造函数,系统会隐式地调用父类的无参构造函数
End!
C#中的虚函数virtual的更多相关文章
- cc38b_demo_C++_异常_(2)txwtech在异常中使用虚函数-多态
//cc38b_demo,21days_C++_异常_(2)txwtech20200121在异常中使用虚函数-多态 //--异常层次结构//*异常的类-创建自己的异常类//*异常派生-就是继承//*异 ...
- C++中的虚函数解析[The explanation for virtual function of CPlusPlus]
1.什么是虚函数? ...
- C++中的虚函数(表)实现机制以及用C语言对其进行的模拟实现
tfref 前言 C++对象的内存布局 只有数据成员的对象 没有虚函数的对象 拥有仅一个虚函数的对象 拥有多个虚函数的对象 单继承且本身不存在虚函数的继承类的内存布局 本身不存在虚函数(不严谨)但存在 ...
- 关于在C#中构造函数中调用虚函数的问题
在C#中如果存在类的继承关系,应避免在构造函数中调用虚函数.这是由于C#的运行机制造成的,原因如下: 新建一个类实例时,C#会先初始化该类(对类变量赋值,并将函数记在函数表中),然后再初始化父类.构造 ...
- C++ 构造函数中调用虚函数
我们知道:C++中的多态使得可以根据对象的真实类型(动态类型)调用不同的虚函数.这种调用都是对象已经构建完成的情况.那如果在构造函数中调用虚函数,会怎么样呢? 有这么一段代码: class A { p ...
- C++箴言:避免构造或析构函数中调用虚函数
如果你已经从另外一种语言如C#或者Java转向了C++,你会觉得,避免在类的构造函数或者析构函数中调用虚函数这一原则有点违背直觉.但是在C++中,违反这个原则会给你带来难以预料的后果和无尽的烦恼. 正 ...
- 读书笔记 effective c++ Item 9 绝不要在构造函数或者析构函数中调用虚函数
关于构造函数的一个违反直觉的行为 我会以重复标题开始:你不应该在构造或者析构的过程中调用虚函数,因为这些调用的结果会和你想的不一样.如果你同时是一个java或者c#程序员,那么请着重注意这个条款,因为 ...
- C#中的虚函数及继承关系
转载:http://blog.csdn.net/suncherrydream/article/details/8423991 若一个实例方法声明前带有virtual关键字,那么这个方法就是虚方法. 虚 ...
- C#虚函数virtual详解
在面向对象编程中,有两种截然不同的继承方式:实现继承和接口继承.在实现继承时候,在Java中,所有函数默认都是virtual的,而在C#中所有函数并不默认为virtual的,但可以在基类中通过声明关键 ...
随机推荐
- Google开源PDF软件库
Google开启了一个叫做PDFium的PDF软件库开源项目,开发人员能够将其纳入各种平台应用中. 据Google的Chromium项目的布道师François Beaufort称,PDFium将被包 ...
- 201871010102-常龙龙《面向对象程序设计(java)》第八周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...
- 201871010114-李岩松《面向对象程序设计(java)》第十三周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...
- 201871010105-曹玉中《面向对象程序设计(java)》第八周学习总结
201871010105-曹玉中<面向对象程序设计(java)>第八周学习总结 项目 内容 <面向对象程序设计(java)> https://www.cnblogs.com/n ...
- robotframework-post request请求携带上一个请求返回的cookie
公司的接口服务需要先登录,获取服务端的cookie后,在后续的请求中携带这个cookie才能够访问 在尝试用RF工具进行自动化接口测试时,发现先访问登录接口之后,接着请求其他接口时没有自动携带上次请求 ...
- js中,null, '',undefined的区别
在js中有三种值都可以代表false "",null,undefined 那么他们之间到底有什么区别呢 首先我们先看这三种值得类型 ""代表了一个没有字符的字 ...
- centos7中运行ifconfig提示“-bash: ifconfig: command not found”解决方案
linux系统查看ip地址常用命令是[ifconfig], CentOS 7.0最小安装是没有ifconfig命令怎么办? 1.用[ip addr]查看; 2.就是安装ifconfig命令 1.输入[ ...
- SWA2G422&485JK2G基础篇: STM32+W5500实现MQTT通信控制,485/422透传通信
说明 这节实现的功能: STM32+W5500实现MQTT通信控制 细节功能: 1.DHCP动态获取IP 2.DNS域名解析 3.网口<--MQTT-->485/422透传通信 测试准备工 ...
- Linux性能优化实战学习笔记:第五十八讲
一.上节回顾 专栏更新至今,咱们专栏最后一部分——综合案例模块也要告一段落了.很高兴看到你没有掉队,仍然在积极学习思考.实践操作,并热情地分享你在实际环境中,遇到过的各种性能问题的分析思路以及优化方法 ...
- IDEA 部署Tomcat教程(透彻理解操作)
目录 首先我们看一下 IDEA 里的当前项目结构配置 设置 Web 资源目录和 Tomcat读取的 web.xml 配置文件 Tomcat 的 Run/Debug 配置 处理常见问题 Web资源找不到 ...