一、先理清继承 → 多态 → VTable 的关系继承子类复用父类的成员还能重写 / 扩展多态父类引用指向子类对象调用方法时自动执行子类的实现运行时决定虚方法表VTableC# 实现多态的底层数据结构CLR 靠它找到正确要执行的方法一句话总结继承让多态成为可能虚方法表让多态能够真正运行。二、基础概念快速回顾1. 继承 (Inheritance)一个类子类 / 派生类可以复用另一个类父类 / 基类的字段、属性、方法关键字:单继承一个类只能有一个直接父类// 父类 public class Animal { public void Eat() Console.WriteLine(吃食物); } // 子类继承 Animal public class Dog : Animal { public void Bark() Console.WriteLine(汪汪叫); }Dog自动拥有Eat()还能新增自己的Bark()2. 多态 (Polymorphism)定义同一个父类引用指向不同子类对象调用同名方法会执行对应子类自己的逻辑。实现多态必须用三个关键字virtual父类方法标记为虚方法可被重写override子类重写虚方法abstract/interface也能实现多态原理一致多态代码示例// 父类标记虚方法 public class Animal { public virtual void Speak() { Console.WriteLine(动物叫); } } // 子类1重写 public class Dog : Animal { public override void Speak() { Console.WriteLine(汪汪汪); } } // 子类2重写 public class Cat : Animal { public override void Speak() { Console.WriteLine(喵喵喵); } }多态核心用法// 父类引用 指向 子类对象 Animal animal1 new Dog(); Animal animal2 new Cat(); // 运行时自动执行对应子类的方法 animal1.Speak(); // 汪汪汪 animal2.Speak(); // 喵喵喵三、虚方法表 VTable 原理1. 什么是 VTableVTableVirtual Method Table虚方法表是.NET CLR 在内存中为每个包含虚方法的类创建的一个方法地址数组。作用运行时快速找到应该执行哪个重写方法→ 实现多态。2. VTable 生成规则每个有虚方法的类都会生成一张独立的 VTable子类 VTable完全复制父类 VTable如果子类重写override了虚方法就替换表中对应的方法地址每个对象实例内部都藏着一个指针TypeHandle指向自己类的 VTable3. 内存结构图解文字版以上面的Animal/Dog/Cat为例① 父类 Animal VTable[0]Animal.Speak()② 子类 Dog VTable复制后替换[0]Dog.Speak() // 重写了替换父类方法③ 子类 Cat VTable[0]Cat.Speak() // 重写了替换父类方法4. 多态执行流程CLR 底层步骤当你执行Animal animal new Dog(); animal.Speak();CLR 做了 4 步看animal引用指向的真实对象Dog找到对象里的TypeHandle指针定位到Dog 的 VTable根据方法索引找到Dog.Speak()并执行这就是多态的底层真相不是看引用类型是看对象真实类型四、关键关键字对比关键字作用是否进 VTablevirtual父类声明可被重写✅ 进入 VTableoverride子类重写替换 VTable 方法地址✅ 替换 VTable 项new子类隐藏父类方法不是重写❌ 不进 VTable不实现多态特别注意new关键字不会生成多态五、VTable 核心特性总结类级别不是对象级别一个类只有一张 VTable所有对象共享这张表继承时复制 重写时替换子类完全继承父类虚方法表重写就替换对应位置运行时绑定晚绑定方法地址不是编译时写死而是运行时查表决定只有虚方法 / 重写方法才进 VTable普通实例方法、静态方法不进虚方法表继承子类复用父类 ↓ 父类加 virtual子类加 override ↓ CLR 为每个类生成 VTable ↓ 子类 VTable 复制父类重写则替换方法地址 ↓ 父类引用指向子类对象 ↓ 运行时通过对象指针 → 找到 VTable → 执行正确方法 ↓ 【多态实现】总结继承是多态的语法基础让子类可以共享父类成员多态是父类引用指向子类对象执行子类重写方法VTable虚方法表是 CLR 为类创建的方法地址数组靠它实现运行时多态核心机制子类复制父类 VTable → 重写替换方法地址 → 运行时查表调用virtual/override开启多态new不参与多态