0

0

c# 继承和多态详解

月夜之吻

月夜之吻

发布时间:2026-01-23 09:11:29

|

315人浏览过

|

来源于php中文网

原创

继承是多态的结构基础,多态是继承的行为表现;abstract用于父类只定义契约不实现时,virtual用于提供默认行为且允许覆盖;多态仅在父类引用调用虚/抽象方法时生效。

c# 继承和多态详解

继承和多态不是两个独立概念,而是一体两面:继承是结构基础,多态是行为表现——没继承,多态无从谈起;没抽象或虚成员,多态就只是普通调用。

什么时候必须用 abstract

当你在父类中「只定义行为契约,不提供实现」时,就必须用 abstract。比如所有动物都要 MakeSound(),但狗叫、猫叫、鸟鸣各不相同,父类无法写死逻辑。

  • 抽象方法必须放在 abstract class 中,且子类非抽象时,override 是强制的
  • 抽象类可以没有抽象方法(比如只做类型约束或共享字段)
  • 不能 new 抽象类实例,哪怕它有构造函数
  • 错误现象:'Animal' does not implement inherited abstract member 'Animal.MakeSound()' —— 子类忘了加 override 或漏了方法体

什么时候该用 virtual 而不是 abstract

当父类能提供一个「合理默认行为」,但允许子类按需覆盖时,用 virtual。比如 ToString() 默认返回类型名,子类可重写为返回更友好的格式。

Inworld.ai
Inworld.ai

InWorldAI是一个AI角色开发平台,开发者可以创建具有自然语言、上下文意识和多模态的AI角色,并可以继承到游戏和实时媒体中

下载
  • 虚方法可以被子类 override,也可以不重写,直接沿用父类逻辑
  • 子类中若想调用父类原版实现,得显式写 base.MethodName()
  • 常见误用:把本该是 virtual 的方法写成 privatesealed,导致子类无法扩展
  • 性能影响极小,但过度虚化(比如每个 getter 都 virtual)会轻微增加虚表查找开销,一般无需担心

多态真正生效的两个典型场景

多态不是“写了 override 就自动多态”,它只在「通过父类引用调用虚/抽象方法」时才触发。关键看变量声明类型,不是实际对象类型。

Animal a1 = new Dog();
Animal a2 = new Cat();
Console.WriteLine(a1.MakeSound()); // 输出 "Woof!"
Console.WriteLine(a2.MakeSound()); // 输出 "Meow!"
  • 参数多态:void Feed(Animal animal) { animal.Eat(); } —— 传 Dog 就执行 Dog.Eat(),传 Bird 就执行 Bird.Eat()
  • 返回值多态:Animal Create(string type) => type switch { "dog" => new Dog(), "cat" => new Cat() }; —— 调用方只需按 Animal 处理,不用关心具体类型
  • 容易踩的坑:用子类变量直接调用,比如 Dog d = new Dog(); d.MakeSound(); —— 这走的是静态绑定,不触发多态,哪怕方法是 virtualabstract
  • 注意:只有 virtualabstractoverride 成员参与多态;privatestaticsealed override 均不参与

protectedbase 在继承链中的真实作用

protected 不是“给子类用的 public”,而是「仅限派生类内部访问」的访问修饰符;base 是子类访问父类成员的唯一安全通道。

  • protected 成员可在子类中直接使用(如 this.Name),但不能通过子类实例访问(new Dog().Name 报错)
  • 子类构造函数必须显式或隐式调用基类构造函数;若基类无无参构造,子类必须用 : base(...) 指定
  • 常见错误:base 调用位置不对(必须是构造函数第一行)、或在静态方法里误用 base
  • 不要用 protected 暴露内部状态,优先考虑 protected virtual 方法供子类定制行为,而非暴露字段

最常被忽略的一点:多态依赖运行时类型信息(RTTI),而 .NET 的 JIT 编译器对虚调用做了高度优化,所以别因“怕慢”而回避 virtual —— 真正的性能瓶颈几乎从来不在这里,而在设计失当导致的深层继承链或过度抽象。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1010

2023.08.02

switch语句用法
switch语句用法

switch语句用法:1、Switch语句只能用于整数类型,枚举类型和String类型,不能用于浮点数类型和布尔类型;2、每个case语句后面必须跟着一个break语句,以防止执行其他case的代码块,没有break语句,将会继续执行下一个case的代码块;3、可以在一个case语句中匹配多个值,使用逗号分隔;4、Switch语句中的default代码块是可选的等等。

569

2023.09.21

Java switch的用法
Java switch的用法

Java中的switch语句用于根据不同的条件执行不同的代码块。想了解更多switch的相关内容,可以阅读本专题下面的文章。

441

2024.03.13

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

27

2025.11.27

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

27

2025.11.27

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

27

2025.11.27

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

186

2023.11.23

java中void的含义
java中void的含义

本专题整合了Java中void的相关内容,阅读专题下面的文章了解更多详细内容。

134

2025.11.27

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP基础入门课程
PHP基础入门课程

共33课时 | 2.2万人学习

前端系列快速入门课程
前端系列快速入门课程

共4课时 | 0.4万人学习

C# 教程
C# 教程

共94课时 | 11.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号