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
相关产品推荐
相关产品推荐

