C# 核心进阶:深度解析继承(Inheritance)与多态机制

在面向对象编程(OOP)中,继承是代码复用和构建类层次结构的核心。通过继承,子类可以扩展或定制基类的功能,而无须从零开始构建。本文将带你深入探索 C# 继承的高级特性,掌握多态、虚函数、类型转换及构造器执行顺序等关键技术点。


1. 多态(Polymorphism)与引用转换

多态是继承的灵魂。在 C# 中,引用是多态的,这意味着父类型的变量可以指向其子类的对象。

引用转换

  • 向上转换(Upcasting):从子类引用创建基类引用。这是隐式的,且仅影响引用类型,不影响被引用的对象本身。
  • 向下转换(Downcasting) :从基类引用创建子类引用。这必须是显式的,因为它在运行时可能失败并抛出异常。

类型转换工具

为了安全地进行向下转换,C# 提供了以下运算符:

  • as 运算符 :转换失败时返回 null 而非抛出异常。
  • is 运算符:检查对象是否满足特定模式(如是否属于某个特定类),常用于转换前的类型检查。
  • 模式变量 :C# 支持在 is 检查的同时引入变量(如 if (obj is Subclass s)),引入的变量可立即使用。

2. 虚函数成员与重写

子类可以通过重写基类的成员来改变其行为。

  • virtual 关键字:允许在子类中被重写。方法、属性、索引器和事件均可声明为虚成员。
  • override 关键字:用于提供虚成员的特定实现。重写时,方法的签名、返回值和访问权限必须保持一致。
  • 协变返回类型(C# 9):允许重写方法时返回比基类定义更具体的派生类型。

⚠️ 安全警告:从构造器调用虚方法具有潜在危险。因为子类重写的方法可能会在子类字段尚未完全初始化之前被调用。


3. 抽象类与密封类

  • 抽象类 (abstract) :不能被实例化,仅作为基类使用。它可以包含不提供默认实现的抽象成员,强制子类实现这些成员。
  • 密封类 (sealed) :防止类被继承。同样,sealed 也可以作用于重写的函数成员,防止其在更深层的子类中被再次重写。

4. 隐藏继承成员(Shadowing)

当子类定义了与基类同名的成员时,会发生成员隐藏

  • 编译器默认会发出警告。
  • 使用 new 修饰符 可以明确告诉编译器这种隐藏是有意为之,从而消除警告。
  • 注意:new 修饰符隐藏成员与 override 重写成员在多态下的表现完全不同。

5. base 关键字的妙用

base 关键字在子类中有两个核心用途:

  1. 访问基类成员:调用被子类重写或隐藏的基类函数实现。
  2. 调用基类构造器:在子类构造器中显式指定调用父类的哪个构造方法。

6. 构造器的执行与初始化顺序

继承体系下的对象实例化有着严格的执行顺序,理解这一点对排查 Bug 至关重要:

总体原则

  1. 基类构造器优先:基类的初始化总是先于子类的特定初始化执行。
  2. 隐式调用 :如果子类构造器未显式使用 base 关键字,编译器会自动尝试调用基类的无参数构造器。

详细步骤

阶段 执行动作 顺序
初始化阶段 字段初始化 & 计算基类构造器参数 从子类到基类
执行阶段 构造器方法体执行 从基类到子类

7. 方法重载与解析

当重载方法在继承体系中被调用时,编译器会根据以下规则决定执行哪个版本:

  • 优先匹配最明确的类型:选择参数类型最贴近传入实参的重载版本。
  • 静态决定 :具体调用哪个重载是在编译时静态决定的,而不是在运行时动态决定的。

技术总结

继承不仅是"获取父类的代码",更是一种"是一个(is-a)"的逻辑关系。通过合理使用 virtualabstractsealed,可以构建出既灵活又安全的类层次结构。在处理构造器时,务必注意字段初始化与方法体执行的先后逻辑。

相关推荐
cici1587410 小时前
基于MATLAB的TERCOM算法实现与优化
开发语言·matlab
天上飞的粉红小猪10 小时前
c++的IO流
开发语言·c++
学嵌入式的小杨同学10 小时前
【嵌入式 Linux 实战 1】Ubuntu 环境搭建 + 目录结构详解:嵌入式开发入门第一步
linux·c语言·开发语言·数据结构·vscode·vim·unix
⑩-10 小时前
JUC-场景题
java·开发语言
a程序小傲10 小时前
京东Java面试被问:基于Gossip协议的最终一致性实现和收敛时间
java·开发语言·前端·数据库·python·面试·状态模式
tqs_1234510 小时前
Spring Boot 的自动装配机制和 Starter 的实现原理
开发语言·python
程序员小白条10 小时前
面试 Java 基础八股文十问十答第二十二期
java·开发语言·数据库·面试·职场和发展·毕设
编程大师哥10 小时前
JavaScript 和 Python 哪个更适合初学者?
开发语言·javascript·python
建军啊11 小时前
php伪协议、代码审计工具和实战
开发语言·php