1. 虚方法关键字?
Virtual
2. 虚方法运行的周期?
虚函数在编译期间是不被静态编译的, 它的相对地址是不确定的, 它会根据运行时对象实例来动态判断要调用的函数, 其中那个申明时定义的类叫申明类, 执行实例化的那个类叫做实例类.
3. 函数运行的检查流程:
1 当调用一个对象的函数时, 系统会直接去检查这个对象的申明定义的类 (申明类), 检查调用的函数是否为虚函数, 如果不是虚函数, 那么它就执行该函数. 而如果有 Viirtual 关键字 (虚函数), 那么它
就不会立即执行该函数. 而是转去检查对象的实例类. 在这个实例类里, 它会检查这个实例类中是否有重现实现该函数 (Override), 如果有就不再找了, 马上执行该实例类中的这个重新实现的函数
而如果每天有, 系统就会不停的往上找实例类, 直到找到第一个重载了该函数的父类为止, 然后执行父类里重载后的的函数
另注意: 虚函数里必须有方法体.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace ConsoleHelp
- {
- public class RunVirtual
- {
- /// <summary>
- /// 虚方法说明以及代码
- /// </summary>
- public void TestRunVirtual() {
- // 注意: 虚方法不允许 static, abstract, 或 override 修饰符
- TestA A;// 定义一个 a 这个 A 类的对象. 这个 A 就是 a 的申明类
- TestA B;// 定义一个 b 这个 A 类的对象. 这个 A 就是 b 的申明类
- TestA C;// 定义一个 c 这个 A 类的对象. 这个 A 就是 b 的申明类
- TestA D;// 定义一个 d 这个 A 类的对象. 这个 A 就是 b 的申明类
- A = new TestA();// 实例化 a 对象, A 是 a 的实例类
- B = new TestB();// 实例化 b 对象, B 是 b 的实例类
- C = new TestC();// 实例化 b 对象, C 是 b 的实例类
- D = new TestD();// 实例化 b 对象, D 是 b 的实例类
- A.Fuctio();// 先检查声明类 A, 发现是虚函数, 跳出检查实例类即为本身, 执行 A 的 Fuctio 方法
- B.Fuctio();// 先检查声明类 A, 发现是虚函数, 跳出检查实例类, 实例类 B 中有重写, 执行重写方法 Fuctio
- C.Fuctio();// 先检查声明类 A, 发现是虚函数, 跳出检查实例类, 实例类 C 中没有重写, 找父类 B(继承了 B 类), 执行 B 类中重写方法 Fuctio
- D.Fuctio();// 先检查声明类 A, 发现是虚函数, 跳出检查实例类, 实例类 D 中虽然有声明了 Fuctio 方法, 但并没有重写 Fuction, 找父类 A, 发现为本身, 执行 A 类的 Fuctio
- }
- }
- }
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace ConsoleHelp
- {
- public class TestA
- {
- public virtual void Fuctio() {
- Console.Write("Fuction in A");
- }
- }
- public class TestB:TestA {
- public override void Fuctio()
- {
- Console.Write("Fuction in B");
- }
- }
- public class TestC : TestB {
- }
- public class TestD : TestA {
- public void Fuctio() {
- Console.Write("Fuction in D");
- }
- }
- }
来源: http://www.bubuko.com/infodetail-2935370.html