C#入门(9):多态介绍与代码演示

多态性是面向对象编程的一个核心概念,它允许你使用一个父类引用来指向一个子类对象。这可以使程序具有可扩展性,并且可以用来实现一些高级编程技术,如接口、事件、抽象类等。

多态相关的概念

以下是一些在C#中使用多态性的关键概念:

虚方法 (Virtual Methods)

在C#中,一个类可以声明一个或多个虚方法。一个虚方法有一个基础实现,可以在派生类中被覆写。为了覆写一个方法,派生类必须声明该方法,并使用override关键字。然后,当通过基类引用调用一个虚方法时,会根据引用的实际类型来调用正确的方法实现。

抽象方法 (Abstract Methods)

一个抽象方法是一个没有实现的方法,它在抽象类中声明,并且必须在任何非抽象的派生类中实现。当通过基类引用调用一个抽象方法时,会根据引用的实际类型来调用正确的方法实现。

接口 (Interfaces)

在C#中,一个接口可以被任何类实现,接口定义了一组方法和属性,但是没有提供实现。当一个类实现了一个接口,它保证了该类提供了接口定义的所有方法和属性。这意味着你可以通过接口引用来调用这些方法和属性,而不用关心对象的实际类型。

基类引用派生类对象

多态性的一个关键特性是,你可以使用基类的引用或接口的引用来引用派生类的对象。当你通过这样的引用调用一个方法时,CLR会根据实际的对象类型来确定应该调用哪个方法。这使得你可以写出更具有通用性的代码,这些代码可以处理任何派生自特定基类或实现特定接口的对象。

例如,如果你有一个Animal类和一些派生自Animal的类,如DogCat,你可以写一个方法,该方法接收一个Animal引用,并通过这个引用调用MakeSound方法。不论传入的实际对象是Dog还是Cat,都可以正确地调用对应的MakeSound方法。这样,你就不需要为DogCat分别写两个方法。

多态性是一个强大的工具,它可以使你的代码更加灵活和可扩展。通过理解和正确使用多态性,你可以提高你的代码质量,并写出更具有可维护性和可扩展性的代码。

在C#中,多态表现为以下两种形式:

编译时多态:这是通过方法重载和运算符重载实现的。在编译时,编译器就可以根据方法签名或运算符参数的数量和类型确定要调用的具体方法或运算符。
编译时多态,也被称为静态多态或早期绑定,是在编译时期确定被调用的方法或属性的机制。在C#中,静态多态主要通过两种方式实现:方法重载和运算符重载。

下面分别介绍这两种功能多态

编译时多态

方法重载(Method Overloading)

方法重载允许在同一类中定义多个名称相同但参数列表不同的方法。编译器根据方法被调用时提供的参数类型和数量来确定应该调用哪个方法。

public class Printer
{public void Print(int i){Console.WriteLine($"Printing int: {i}");}public void Print(double d){Console.WriteLine($"Printing double: {d}");}public void Print(string s){Console.WriteLine($"Printing string: {s}");}
}// 使用
Printer printer = new Printer();
printer.Print(10); // 输出 "Printing int: 10"
printer.Print(3.14); // 输出 "Printing double: 3.14"
printer.Print("Hello world"); // 输出 "Printing string: Hello world"

在上述例子中,Printer类定义了三个重载的Print方法,分别接收一个intdoublestring类型的参数。编译器会根据Print方法被调用时提供的参数类型来选择正确的方法。

运算符重载(Operator Overloading)

C#也允许我们对类或结构体的运算符进行重载,这也是一种编译时多态。我们可以定义新的运算符,以便在类或结构体的对象上执行特定的操作。

public struct Point
{public int X { get; set; }public int Y { get; set; }public static Point operator +(Point a, Point b){return new Point { X = a.X + b.X, Y = a.Y + b.Y };}
}// 使用
Point p1 = new Point { X = 1, Y = 1 };
Point p2 = new Point { X = 2, Y = 2 };
Point p3 = p1 + p2; // p3.X = 3, p3.Y = 3

在上述例子中,我们为Point结构体重载了+运算符,使得我们可以直接将两个Point对象相加。

注意,虽然静态多态在编译时期就确定了被调用的方法或属性,但是仍然需要我们在编写代码时遵循一些规则,例如,对于方法重载,重载的方法必须在参数类型或参数数量上有所不同;对于运算符重载,只能重载一部分预定义的运算符,不能创建新的运算符,也不能重载一些特定的运算符(比如&&||等)。

运行时多态:这是通过虚方法、抽象方法和接口实现的。在运行时,CLR(公共语言运行时)根据对象的实际类型来决定要调用的具体方法。

运行时多态

以下是一个运行时多态的例子:

public class Animal
{public virtual void MakeSound(){Console.WriteLine("The animal makes sound");}
}public class Dog : Animal
{public override void MakeSound(){Console.WriteLine("The dog barks");}
}public class Cat : Animal
{public override void MakeSound(){Console.WriteLine("The cat meows");}
}// 在其他地方使用
Animal myAnimal = new Dog();
myAnimal.MakeSound(); // 输出 "The dog barks"myAnimal = new Cat();
myAnimal.MakeSound(); // 输出 "The cat meows"

在这个例子中,Animal类定义了一个虚方法MakeSound,Dog类和Cat类覆写了这个方法。在运行时,尽管myAnimal的编译时类型是Animal,但是CLR会根据其运行时类型(即实际的对象类型)来调用正确的MakeSound方法。这就是多态的作用,使得我们可以写出更通用的代码,而不需要知道或检查对象的具体类型。

多态的主要优点是促进了代码的复用和模块化,使得代码更加灵活和可扩展。通过使用多态,我们可以写出可以处理基类和派生类的通用代码,而不需要为每一个具体的类写特定的代码。

接口实现多态

在C#中,接口是一种强大的工具,用于实现多态。接口定义了一组方法和属性,但没有提供实现。任何实现了特定接口的类都保证提供接口定义的所有方法和属性。

下面是一个使用接口实现多态的例子:

public interface IAnimal
{void MakeSound();
}public class Dog : IAnimal
{public void MakeSound(){Console.WriteLine("The dog barks");}
}public class Cat : IAnimal
{public void MakeSound(){Console.WriteLine("The cat meows");}
}// 在其他地方使用
IAnimal myAnimal = new Dog();
myAnimal.MakeSound(); // 输出 "The dog barks"myAnimal = new Cat();
myAnimal.MakeSound(); // 输出 "The cat meows"

在这个例子中,IAnimal接口定义了一个MakeSound方法,Dog类和Cat类都实现了这个接口,并提供了MakeSound方法的实现。然后,我们可以创建一个IAnimal引用,并让它引用一个Dog对象或一个Cat对象。当我们通过这个引用调用MakeSound方法时,CLR会根据实际的对象类型来调用正确的方法实现。这就是多态的作用,使得我们可以写出更通用的代码,而不需要知道或检查对象的具体类型。

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

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

相关文章

centos7卸载mongodb数据重新安装时无法安装的问题

如果卸载不干净直接用 sudo find / -name mongo 查询所有关于mongo的文件,然后一个个去删除。 当然最好的办法还是去看日志信息。 直接去查看日志信息 sudo cat /var/log/mongodb/mongod.log 根据提示信息说这个没有权限操作 直接删除即可,都是之前…

全球首款容器计算产品重磅发布,激活上云用云新范式

云布道师 10 月 31 日,杭州云栖大会上,阿里云云原生应用平台负责人丁宇宣布,阿里云容器计算服务 ACS 正式发布!ACS 将大幅降低企业和开发者用云门槛,真正将 Serverless 理念大规模落地。 容器计算服务 ACS&#xff0c…

ssm+vue的OA办公系统(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频: ssmvue的OA办公系统(有报告)。Javaee项目,ssm vue前后端分离项目。 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 项目介绍&a…

Windows网络「SSL错误问题」及解决方案

文章目录 问题方案 问题 当我们使用了神秘力量加持网络后,可能会和国内的镜像源网站的之间发生冲突,典型的有 Python 从网络中安装包,如执行 pip install pingouin 时,受网络影响导致无法完成安装的情况: pip config…

idea中的sout、psvm快捷键输入,不要太好用了

目录 一、操作环境 二、psvm、sout 操作介绍 2.1 psvm,快捷生成main方法 2.2 sout,快捷生成打印方法 三、探索 psvm、sout 底层逻辑 一、操作环境 语言:Java 工具: 二、psvm、sout 操作介绍 2.1 psvm,快捷生成m…

笔尖笔帽检测3:Android实现笔尖笔帽检测算法(含源码 可是实时检测)

目录 1. 前言 2.笔尖笔帽检测方法 (1)Top-Down(自上而下)方法 (2)Bottom-Up(自下而上)方法: 3.笔尖笔帽关键点检测模型训练 4.笔尖笔帽关键点检测模型Android部署 (1) 将Pytorch模型转换ONNX模型 (2) 将ONNX模…

FPGA模块——IIC协议(读写PCF8591)

FPGA模块——IIC协议(读取PCF8591) PCF8591/AT8591芯片对iic协议的使用 PCF8591/AT8591芯片 低功耗8位CMOS数据采集设备,4路模拟输入,1路模拟输出,分时多路复用,读取数据用串型iic总线接口,最大…

2.5计划任务远程管理

2.5计划任务/远程管理 一、计划任务 1、计划任务概念解析 在Linux操作系统中,除了用户即时执行的命令操作以外,还可以配置在指定的时间、指定的日期 执行预先计划好的系统管理任务(如定期备份、定期采集监测数据)。RHEL6系统中…

Redis:Java客户端

前言 "在当今大数据和高并发的应用场景下,对于数据缓存和高效访问的需求日益增长。而Redis作为一款高性能的内存数据库,以其快速的读写能力和丰富的数据结构成为众多应用的首选。与此同时,Java作为广泛应用于企业级开发的编程语言&…

新安装win11,搜索框无法输入的问题

正确的做法是如下: 1首先进入win11系统,在搜索框中输入“ 控制面板 ”将其打开2在控制面板中找到“时间和语言“ 标题 再选择“ 语言和区域”, 标题 在显示的语言上面,点击省略号,进入语言选项 标题 在键盘处,删除不需要的输入法…

想面试前端工程师,必须掌握哪些知识和技能?【云驻共创】

在当今的数字化时代,前端工程师扮演着至关重要的角色。他们负责设计和开发用户界面,使得用户能够与应用程序或网站进行互动。为了找到最出色的前端工程师,你需要了解哪些技能和知识是必备的,同时也要掌握一些面试技巧和常见的面试…

Java 开源重试类 guava-retrying 使用案例

使用背景 需要重复尝试执行某些动作&#xff0c;guava-retrying 提供了成型的重试框架 依赖 <dependency><groupId>com.github.rholder</groupId><artifactId>guava-retrying</artifactId><version>${retrying.version}</version>…

Python基础学习019--跳过

# 未完成的代码或不想让他执行的代码:使用装饰器跳过,书写在TestCase文件中 # 直接标记跳过:unittest.skip(跳过原因)# 根据条件判断跳过:unittest.skipIf(判断条件,跳过的原因),跳进成立则跳过 import unittestversion 31class TestDemo(unittest.TestCase):unittest.skip(没…

contos7 设置mongodb需账号密码访问

要设置密码访问MongoDB&#xff0c;您可以按照以下步骤进行操作&#xff1a; 连接到MongoDB实例&#xff1a;使用MongoDB的命令行工具&#xff08;mongo shell&#xff09;连接到MongoDB实例。在终端中输入以下命令&#xff1a; mongo切换到admin数据库&#xff1a;登录到Mongo…

90天,广告商单43张,小红书AI庭院风视频制作详解教程

今天给大家分享一个目前在小红书很火的AI绘画商单号案例。 首先给大家看看案例视频形态 这类视频内容非常简单&#xff0c;主要展示农家庭院的别致景色。通过AI绘画工具生成图片&#xff0c;再利用剪辑工具将画面增加动态元素&#xff0c;让整个视频逼真鲜活&#xff0c;加上…

PHP中isset() empty() is_null()的区别

在PHP中&#xff0c;isset()、empty()和is_null()是用于检查变量状态的三个不同的函数。它们分别用于检查变量是否已设置、是否为空以及是否为null。在本文中&#xff0c;我们将详细解释这三个函数的用法、区别和适当的使用场景。 isset(): isset()函数用于检查一个变量是否已…

《洛谷深入浅出基础篇》 P5250 木材仓库————集合应用实例

上链接&#xff1a; P5250 【深基17.例5】木材仓库 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P5250上题干&#xff1a; 题目描述 博艾市有一个木材仓库&#xff0c;里面可以存储各种长度的木材&#xff0c;但是保证没有两个木材的长度是…

【心得】SQL注入知识清单

sql注入的类型 类型一&#xff1a;数字型注入和union 注入 http://127.0.0.1/page_detail.php?id1 union select 1,(select password from user where usernameadmin),3 limit 1,2 类型二&#xff1a;字符型注入 前面闭合 后面注释 来逃逸出单引号或者双引号 http://127…

蓝桥杯物联网_STM32L071_1_CubMxkeil5基础配置

CubMx配置&#xff1a; project工程中添加.h和.c文件&#xff1a; keil5配置: 运行&#xff1a; 代码提示与解决中文乱码&#xff1a;

在使用tomcat运行项目时,遇到端口80被占用的情况问题解决

问题描述&#xff1a;Failed to initialize end point associated with ProtocolHandler ["http-bio-80"] java.net.BindException: Address already in use: NET_Bind <null>:80 在学习springmvc的时候&#xff0c;跟着黑马视频进行学习&#xff0c;结果&…