子类中的Print方法未被调用,为何执行父类的Print方法?
为什么父类引用调用方法输出父类内容而非子类?
你的代码里,子类的Print方法并没有实现多态重写,而是做了方法隐藏,这就是问题的核心:
class Base { public void Print() { Console.WriteLine("Base"); } } class Child : Base { public void Print() { Console.WriteLine("Child"); } }
原因解析
C#里的实例方法默认是非虚方法,子类中定义的同名同签名方法,默认只是在子类的作用域内创建了一个全新的方法,和父类的Print没有多态关联——它只是"遮住"了父类的方法,而非替换。
当你用Base obj = new Child();这种父类引用指向子类实例的方式调用obj.Print()时,C#编译器会根据引用的静态类型(也就是Base)来匹配方法,而不是看实例的实际类型(Child),所以最终执行的是Base类的Print方法,输出"Base"。
实现预期效果的方法
如果想要让调用时根据实例的实际类型执行对应方法(多态),需要修改代码:
- 在父类的
Print方法前添加virtual关键字,标记它允许被子类重写 - 在子类的
Print方法前添加override关键字,明确重写父类的虚方法
修改后的代码:
class Base { public virtual void Print() { Console.WriteLine("Base"); } } class Child : Base { public override void Print() { Console.WriteLine("Child"); } }
此时再执行Base obj = new Child(); obj.Print();,就会输出"Child"。
另外补充:如果在子类的Print前加new关键字,是明确告诉编译器你要隐藏父类方法(避免编译器警告),但本质还是方法隐藏,不会触发多态——只有当引用的静态类型是Child时,才会调用子类的Print。
内容的提问来源于stack exchange,提问作者Ali Abbasifard
相关产品推荐
相关产品推荐

