C# 里的多态指的是什么?请分别说明编译时多态和运行时多态,并阐述各自在 C# 中是如何实现的。
考察说明
考查对 C# 面向对象多态概念及其两种实现方式的理解。
回答思路
- 【回答框架 1】多态是指同一操作作用于不同对象时产生不同行为的能力,是面向对象三大特性之一。在 C# 中,多态主要分为编译时多态和运行时多态。
- 【回答框架 2】编译时多态通过方法重载实现。在同一个类中定义多个同名方法,但参数列表不同(参数类型、个数或顺序不同),编译器在编译阶段根据调用时传入的参数类型和数量确定具体调用哪个方法,因此也称为静态多态或早期绑定。
- 【回答框架 3】运行时多态通过继承和虚方法重写实现。基类中定义虚方法(使用 virtual 关键字),派生类中重写该方法(使用 override 关键字)。调用时通过基类引用指向派生类对象,程序在运行时根据对象的实际类型动态决定调用哪个方法版本,因此也称为动态多态或晚期绑定。
- 【回答框架 4】实现运行时多态需要满足三个条件:类之间存在继承关系、基类方法声明为虚、派生类重写该方法。例如基类 Animal 定义虚方法 Speak,子类 Dog 和 Cat 分别重写 Speak,当用 Animal 类型的变量分别指向 Dog 和 Cat 实例并调用 Speak 时,会输出各自的声音。
- 【回答框架 5】抽象方法和接口也能实现运行时多态。抽象方法本质上也是虚的,派生类必须重写;接口则定义一组契约,任何实现接口的类都可以被接口引用,从而在运行时调用对应实现。
- 【关键点 1】编译时多态是方法重载,运行期前绑定;运行时多态是虚方法重写,运行期动态绑定。
- 【关键点 2】virtual 和 override 配合使用才构成运行时多态,new 关键字隐藏方法不属于多态。
- 【关键点 3】运行时多态依赖继承和引用类型与实例类型不一致的赋值。
- 【关键点 4】抽象方法和接口也是实现运行时多态的常见手段。
- 【易错点 1】混淆重载(编译时多态)与重写(运行时多态),两者机制完全不同。
- 【易错点 2】认为只有虚方法才能实现多态,忽略接口和抽象方法也是多态的载体。
- 【易错点 3】用 new 关键字隐藏基类方法并误以为是多态重写,实际是重新定义,不是动态绑定。