You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#未用virtual/override,子类同名方法为何未被基类覆盖?

为什么C#中未用virtual/override,子类同名方法仍输出自身结果?

你搞反了逻辑——未用virtual和override时,子类的同名方法不是被基类覆盖,而是隐藏了基类的方法,这是C#里的「方法隐藏(Method Hiding)」机制。

核心原因拆解:

  • 方法隐藏的本质:你在Dog和Cat里写的sound方法,是重新定义了一个和基类同名的新方法,和基类的sound没有继承上的重写关系,只是名字撞了。C#允许这么做,但编译器会给出警告(建议加new关键字显式声明你是故意隐藏基类方法,比如public new void sound())。
  • 调用哪个方法看编译时类型:你Main里的变量dog编译时类型是Dog,cat是Cat,所以编译阶段就确定了要调用子类自己定义的sound方法;如果把变量改成Animal dog = new Dog(),这时候编译时类型是Animal,才会调用基类的sound。

举个对比例子验证:

把你的Main代码改成这样:

Animal animal = new Animal();
Animal dogAsAnimal = new Dog(); // 编译时类型是Animal,运行时是Dog
Dog dog = new Dog();

animal.sound();       // 输出...
dogAsAnimal.sound();  // 输出...(编译时类型是Animal,走基类方法)
dog.sound();          // 输出Woof(编译时类型是Dog,走子类隐藏的方法)

回到你的原代码:因为你用的是Dog dog = new Dog()这种变量声明,编译时类型就是子类本身,自然会调用子类自己的sound方法,而不是基类的。这和你之前理解的「子类方法被基类覆盖」完全是两回事——覆盖(重写)是virtual+override才有的运行时多态,而方法隐藏是编译时就确定的静态绑定。

内容的提问来源于stack exchange,提问作者elektra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 00:50:13