C# 继承与多态详解


.NET学习资料

.NET学习资料

.NET学习资料


在 C# 面向对象编程中,继承与多态是两个极为关键的特性,它们赋予了程序强大的复用性和灵活性。理解并掌握这两个特性,是成为一名优秀 C# 开发者的必经之路。

一、C# 继承

1.1 继承的定义与概念

继承是指一个新类(子类或派生类)可以获取另一个已存在类(父类或基类)的属性和方法。在 C# 中,使用冒号:来表示继承关系。例如:

class Animal
{public string Name { get; set; }public void Eat(){Console.WriteLine($"{Name}正在吃东西");}
}class Dog : Animal
{public void Bark(){Console.WriteLine($"{Name}在汪汪叫");}
}

在上述代码中,Dog类继承自Animal类,这意味着Dog类自动拥有了Animal类的Name属性和Eat方法,同时还可以定义自己特有的Bark方法。

1.2 继承的特性

成员继承:子类会继承父类的公共(public)和受保护(protected)成员,但构造函数和析构函数不会被继承。其中,public成员可以被任何对象访问;protected成员只能被该类本身及其子类对象访问。

构造函数调用顺序:当创建子类对象时,系统会首先调用父类的构造函数,然后再调用子类的构造函数。如果子类构造函数需要调用父类的特定构造函数,可以使用base关键字。例如:

class Animal
{public Animal(){Console.WriteLine("Animal的构造函数被调用");}
}class Dog : Animal
{public Dog() : base(){Console.WriteLine("Dog的构造函数被调用");}
}

执行new Dog();时,会先输出 “Animal 的构造函数被调用”,再输出 “Dog 的构造函数被调用” 。

使用base关键字:在子类中,base关键字用于访问父类的成员。当子类需要调用父类中被重写的方法,或者访问父类的属性时,就可以使用base关键字。例如:

class Animal
{public virtual void Move(){Console.WriteLine("动物在移动");}
}class Dog : Animal
{public override void Move(){base.Move();// 调用父类的Move方法Console.WriteLine("狗在奔跑");}
}

1.3 方法重写(override)

方法重写是指在子类中重新定义父类中已有的虚方法(使用virtual关键字声明的方法)。重写后的方法需要使用override关键字声明,并且方法签名(方法名、参数列表和返回类型)必须与父类中的虚方法一致。例如:

class Shape
{public virtual void Draw(){Console.WriteLine("绘制一个形状");}
}class Circle : Shape
{public override void Draw(){Console.WriteLine("绘制一个圆形");}
}

在这个例子中,Circle类重写了Shape类的Draw方法,当调用Circle对象的Draw方法时,会执行Circle类中重写后的方法。

1.4 继承的优点

代码复用:通过继承,子类可以复用父类的代码,减少重复代码的编写,提高开发效率。例如多个具有相似属性和行为的类,可以提取共同部分到父类,子类只需继承并扩展自己特有的部分。

增强代码的可维护性:当需要修改某个功能时,只需在父类中进行修改,所有子类都会受到影响,而不需要逐个修改每个子类的代码。

体现层次结构关系:清晰地展示了类之间的层次结构,使代码结构更加清晰,易于理解和扩展。

二、C# 多态

2.1 多态的定义与概念

多态是指同一个行为具有多个不同表现形式或形态的能力。在 C# 中,多态主要通过虚方法和抽象类来实现。简单来说,就是可以使用父类的引用来调用子类中重写的方法,在运行时根据对象的实际类型来决定调用哪个类的方法。例如:

class Animal
{public virtual void MakeSound(){Console.WriteLine("动物发出声音");}
}class Dog : Animal
{public override void MakeSound(){Console.WriteLine("汪汪汪");}
}class Cat : Animal
{public override void MakeSound(){Console.WriteLine("喵喵喵");}
}class Program
{static void Main(){Animal animal1 = new Dog();Animal animal2 = new Cat();animal1.MakeSound();// 调用Dog类的MakeSound方法animal2.MakeSound();// 调用Cat类的MakeSound方法}
}

在上述代码中,animal1和animal2虽然都是Animal类型的引用,但它们分别指向Dog和Cat对象,在调用MakeSound方法时,会根据对象的实际类型调用相应子类的方法,这就是多态的体现。

2.2 实现多态的要素

子类重写父类方法:子类必须重写父类中使用virtual关键字声明的虚方法,并且使用override关键字进行声明。

向上转型:将子类对象赋值给父类引用,即使用父类的类型来引用子类对象。例如Animal animal = new Dog(); ,这里将Dog对象赋值给Animal类型的变量animal ,这就是向上转型。

2.3 多态的优点

提高代码的可扩展性:当需要添加新的子类时,不需要修改大量现有的代码,只需要在新子类中重写相应的方法即可。例如在上述动物的例子中,如果要添加一个Pig类,只需要让Pig类继承自Animal类,并重写MakeSound方法,而不需要修改其他类的代码。

增强代码的可维护性:多态使得代码结构更加清晰,每个类只负责自己的功能实现,通过父类引用来调用不同子类的方法,减少了代码的耦合度,便于维护和修改。

提高代码的复用性:可以编写通用的代码,通过父类引用来处理不同子类的对象,实现代码的复用。例如可以编写一个方法,接收Animal类型的参数,然后在方法中调用MakeSound方法,这样这个方法就可以处理任何继承自Animal的子类对象。

三、总结

继承与多态是 C# 面向对象编程中非常重要的特性。继承允许我们复用已有的代码,构建清晰的类层次结构;多态则通过动态绑定,使程序在运行时能够根据对象的实际类型做出不同的行为,提高了代码的灵活性、可扩展性和可维护性。在实际的 C# 开发中,合理运用继承与多态,可以让我们的代码更加简洁、高效和易于维护。随着对 C# 学习的深入,还可以进一步探索抽象类、接口等与继承和多态相关的特性,以更好地发挥面向对象编程的优势 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/11405.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[免费]微信小程序智能商城系统(uniapp+Springboot后端+vue管理端)【论文+源码+SQL脚本】

大家好,我是java1234_小锋老师,看到一个不错的微信小程序智能商城系统(uniappSpringboot后端vue管理端),分享下哈。 项目视频演示 【免费】微信小程序智能商城系统(uniappSpringboot后端vue管理端) Java毕业设计_哔哩哔哩_bilibili 项目介绍…

本地部署DeepSeek-R1保姆级教程

近期,我国一款开源模型 DeepSeek-R1以低成本和高性能震撼了全球科技界。该模型的开源性使开发者能够在本地环境中部署和运行,提供了更高的灵活性和控制力。如果你也想在本地部署 DeepSeek-R1,可以参考以下完整的教程,涵盖Mac 版本…

仿真设计|基于51单片机的贪吃蛇游戏

目录 具体实现功能 设计介绍 51单片机简介 资料内容 仿真实现(protues8.7) 程序(Keil5) 全部内容 资料获取 具体实现功能 利用单片机8*8点阵实现贪吃蛇游戏的控制。 仿真演示视频: 51-基于51单片机的贪吃蛇游…

【4Day创客实践入门教程】Day2 探秘微控制器——单片机与MicroPython初步

Day2 探秘微控制器——单片机与MicroPython初步 目录 Day2 探秘微控制器——单片机与MicroPython初步MicroPython语言基础开始基础语法注释与输出变量模块与函数 单片机基础后记 Day0 创想启程——课程与项目预览Day1 工具箱构建——开发环境的构建Day2 探秘微控制器——单片机…

ubuntu 下使用deepseek

安装Ollama sudo snap install ollama 执行 ollama run deepseek-coder 然后进行等待。。。

消息队列应用示例MessageQueues-STM32CubeMX-FreeRTOS《嵌入式系统设计》P343-P347

消息队列 使用信号量、事件标志组和线标志进行任务同步时,只能提供同步的时刻信息,无法在任务之间进行数据传输。要实现任务间的数据传输,一般使用两种方式: 1. 全局变量 在 RTOS 中使用全局变量时,必须保证每个任务…

本地缓存~

前言 Caffeine是使用Java8对Guava缓存的重写版本,在Spring Boot 2.0中取而代之,基于LRU算法实现,支持多种缓存过期策略。 以下摘抄于https://github.com/ben-manes/caffeine/wiki/Benchmarks-zh-CN 基准测试通过使用Java microbenchmark ha…

Unity Shader Graph 2D - 角色身体电流覆盖效果

在游戏中,通常会有游戏角色受到“电击”的效果,此时游戏角色身体上会覆盖有电流,该效果能表明游戏角色的当前状态,让玩家能够获得更直观更好的体验。 那么如何实现呢 首先创建一个ShaderGraph文件,命名为Current,再创建对应的材质球M_Current。 基础的资源显示 老规矩,…

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.9 广播陷阱:形状不匹配的深层隐患

2.9 广播陷阱:形状不匹配的深层隐患 目录 #mermaid-svg-F0AgBChfSCGzOqa7 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-F0AgBChfSCGzOqa7 .error-icon{fill:#552222;}#mermaid-svg-F0AgBChfSCGzOqa7 …

解锁豆瓣高清海报(二) 使用 OpenCV 拼接和压缩

解锁豆瓣高清海报(二): 使用 OpenCV 拼接和压缩 脚本地址: 项目地址: Gazer PixelWeaver.py pixel_squeezer_cv2.py 前瞻 继上一篇“解锁豆瓣高清海报(一) 深度爬虫与requests进阶之路”成功爬取豆瓣电影海报之后,本文将介绍如何使用 OpenCV 对这些海报进行智…

vue入门到实战 二

目录 2.1 计算属性computed 2.1.1什么是计算属性 2.1.2 只有getter方法的计算属性 2.1.3 定义有getter和setter方法的计算属性 2.1.4 计算属性和methods的对比 2.2 监听器属性watch 2.2.1 watch属性的用法 2.2.2 computed属性和watch属性的对比 2.1 计算属性computed…

【DeepSeek】本地快速搭建DeepSeek

博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 博客内容主要围绕: 5G/6G协议讲解 高级C语言讲解 Rust语言讲解 文章目录 本地快速搭建DeepSeek一、安装及配置ollama二、DeepSeek模型…

Spring WebFlux揭秘:下一代响应式编程框架,与Spring MVC有何不同?

Spring WebFlux和Spring MVC都是Spring家族里的成员,它们都能帮助我们开发Web应用,但工作方式有所不同。 可以把Spring MVC想象成一个服务员,每次有客人(请求)来,它就会专门找一个服务员(线程&a…

基于微信小程序的实习记录系统设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…

MySQL5.5升级到MySQL5.7

【卸载原来的MySQL】 cmd打开命令提示符窗口(管理员身份)net stop mysql(先停止MySQL服务) 3.卸载 切换到原来5.5版本的bin目录,输入mysqld remove卸载服务 测试mysql -V查看Mysql版本还是5.5 查看了环境变量里的…

TensorFlow 简单的二分类神经网络的训练和应用流程

展示了一个简单的二分类神经网络的训练和应用流程。主要步骤包括: 1. 数据准备与预处理 2. 构建模型 3. 编译模型 4. 训练模型 5. 评估模型 6. 模型应用与部署 加载和应用已训练的模型 1. 数据准备与预处理 在本例中,数据准备是通过两个 Numpy 数…

使用朴素贝叶斯对散点数据进行分类

本文将通过一个具体的例子,展示如何使用 Python 和 scikit-learn 库中的 GaussianNB 模型,对二维散点数据进行分类,并可视化分类结果。 1. 数据准备 假设我们有两个类别的二维散点数据,每个类别包含若干个点。我们将这些点分别存…

AI视频编码器(3.2) 《Swin Transformer V2: Scaling Up Capacity and Resolution》

arxiv链接自监督训练用到了SimMIM 论文链接。我觉得,SimMIM与MAE的区别在于,前者只是一个1-layer的prediction head,而后者是多层transformer结构的decoder。可参考Swin Transformer V2(CVPR 2022)论文与代码解读。总结 图中展示了三个创新,从左到右有三处红色结构,分别…

前端进阶:深度剖析预解析机制

一、预解析是什么? 在前端开发中,我们常常会遇到一些看似不符合常规逻辑的代码执行现象,比如为什么在变量声明之前访问它,得到的结果是undefined,而不是报错?为什么函数在声明之前就可以被调用&#xff1f…

Baklib赋能企业提升内容中台构建效率的全新路径解析

内容概要 在当今数字化转型的大潮中,企业面临着前所未有的挑战与机遇。为了顺应市场的发展趋势,提高运营能力,搭建高效的内容中台已成为企业迫在眉睫的任务。内容中台不仅仅是一个技术架构的集合,它更是企业实现数据共享、资源整…