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)"的逻辑关系。通过合理使用 virtual、abstract 和 sealed,可以构建出既灵活又安全的类层次结构。在处理构造器时,务必注意字段初始化与方法体执行的先后逻辑。

相关推荐
吃一碗粉只付一碗钱3 小时前
12-给SPA友好的401和403响应
c#·状态模式
第九序言T4 小时前
Python 数据处理进阶(十八)批量处理同结构文件:一个文件夹一次跑完
开发语言·python·自动化·pandas·数据处理
龙亘川5 小时前
构建城市公共安全数字底座:亘川智城智慧安防系统全维度解读
java·大数据·开发语言·人工智能·信息可视化
程序喵大人5 小时前
【C++入门】内存模型与资源管理 - 09 shared_ptr 和 weak_ptr 解决共享,也带来代价
开发语言·c++·资源管理·智能指针·内存模型
Raas1006 小时前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
专注仿真6 小时前
线性回归和逻辑回归算法详解
开发语言·人工智能·python·大模型训练·控制算法
jimy17 小时前
C++ 中的 `T&&`:右值引用与转发引用
开发语言·c++
呆呆虫127 小时前
用 orjson 加速 SerpBase 响应解析:基准对比与注意事项
开发语言·php
心疼你的一切8 小时前
Python自动发邮件实战定时发报表
大数据·开发语言·python
Wang's Blog9 小时前
Java 项目实战:交友项目 - 用户体系集成总结
java·开发语言·交友