4. 面向对象三大特性:封装、继承、多态,接口与抽象类
面向对象(OOP)是C#面试的核心基础,面试官会从语法实现、设计意图、实际场景三个层次考察你对封装、继承、多态以及接口与抽象类的理解。本章提供3个高频问答卡片,配套回答框架与追问路径,帮助你在答题时展现出“理论扎实 + 落地经验”。
📌 本章重点速览
封装:访问修饰符 + 属性 / 方法控制
继承:is-a 关系 + 重写/隐藏(new/virtual/override)
多态:运行时多态(虚方法/接口) vs 编译时多态(重载)
接口与抽象类:契约 vs 模板,语法区别与设计场景
封装:访问修饰符 + 属性 / 方法控制
继承:is-a 关系 + 重写/隐藏(new/virtual/override)
多态:运行时多态(虚方法/接口) vs 编译时多态(重载)
接口与抽象类:契约 vs 模板,语法区别与设计场景
❓ 面试问题 1:请解释封装的含义,并举例说明在C#中如何实现封装?
| 面试官考察点 | 是否理解封装的核心是“隐藏实现细节,暴露必要接口”;是否掌握访问修饰符(private/protected/internal/public)的选用;是否能在设计层面(如属性、方法、类层次)运用封装。 |
|---|---|
| 回答框架 |
|
| 简短示例回答 | 封装的本质是“内部数据对外部隐藏”。比如定义一个 BankAccount 类,_balance 字段设为 private,通过 public decimal Balance { get; private set; } 暴露只读属性,存款/取款方法内部检查逻辑。这样外部无法直接修改余额,保证了数据安全。 |
| 可能追问 |
|
| 避坑提醒 | ❌ 不要只说“封装就是把字段变成私有就完事”,必须提及“暴露合适接口”和“改变实现不影响调用者”。 ✅ 可以用 .NET 框架中 StringBuilder 类作为封装范例。 |
❓ 面试问题 2:继承如何实现?C#中 virtual、override、new 关键字分别何时使用?
| 面试官考察点 | 是否理解继承的 is-a 关系;是否掌握重写(override)与隐藏(new)的区别;能否在实际设计中避免滥用继承(组合优先原则)。 |
|---|---|
| 回答框架 |
|
| 简短示例回答 | 基类 Animal 有 virtual void Speak(),子类 Dog override Speak() 打印“汪”,Cat override 打印“喵”。另一个子类 RobotDog new Speak() 打印“机械声”,但若通过 Animal 引用调用,则仍然是 Animal.Speak()。这就是 override 与 new 的核心区别:是否参与多态。 |
| 可能追问 |
|
| 避坑提醒 | ❌ 不要认为 new 关键字“重写”了方法,它只是隐藏,基类引用无法调用子类新实现。 ✅ 回答时可以提一下 LSP(里氏替换原则),说明正确使用继承的重要性。 |
❓ 面试问题 3:接口和抽象类有什么区别?实际开发中如何选择?
| 面试官考察点 | 是否清晰区分语法差异(多继承 vs 单继承、默认实现、字段等);是否理解设计意图(契约 vs 模板);能否结合场景(如插件系统用接口,基类通用行为用抽象类)。 |
|---|---|
| 回答框架 |
|
| 简短示例回答 | 抽象类 Animal 有字段 _name 和抽象方法 MakeSound(),子类实现。而接口 IFlyable 定义 Fly(),鸟类、飞机类都可实现。接口多实现,抽象类单继承。C# 8 后接口可以有默认实现,但通常仍用于定义能力契约。 |
| 可能追问 |
|
| 避坑提醒 | ❌ 不要机械背诵“抽象类有方法实现,接口没有”,C# 8 之后接口可以有默认实现。 ✅ 强调设计层面的区分:抽象类代表“家族共性”,接口代表“跨家族能力”。 |
📁 项目案例:在线支付网关(OOP设计实战)
| 项目名称 | 多商户统一支付平台(MPPay) |
|---|---|
| 业务背景 | 公司从单一支付渠道扩展到支持微信、支付宝、银行卡等 6 种支付方式,需设计可扩展的支付网关。 |
| 规模指标 | 日交易量 20万笔,高峰 TPS 800+,接入商户 500+ |
| 技术栈 | .NET 6, ASP.NET Core, EF Core, RabbitMQ, Redis, SQL Server |
| 核心难点 |
|
| 面试高频追问 |
|
| 可迁移回答话术 | “在设计可扩展的支付网关时,我选择用接口定义 IPaymentChannel,包含 Pay、Refund、VerifyCallback 等契约。每个渠道独立实现,通过工厂类获取。对于新增渠道,只需添加新实现类 + 配置文件注册,无需修改现有代码。这体现了 OCP(开闭原则)和依赖倒置。面试官如果追问为什么不用抽象类,我会回答:不同支付渠道之间没有共享字段,接口更轻量;需要共享字段才考虑抽象类。” |
💡 面试加分技巧
当被问到“接口与抽象类”时,主动引出设计模式(策略模式、模板方法模式)和 SOLID 原则,展现你对 OOP 的深度应用。
当被问到“接口与抽象类”时,主动引出设计模式(策略模式、模板方法模式)和 SOLID 原则,展现你对 OOP 的深度应用。