当前位置: 首页 > news >正文

多态性说明

多态

  • 多态性
          • 多态性类型描述
          • 编译时多态和运行时多态的差异
          • go 语言多态性

多态性

多态性类型描述

多态性是面向对象编程中的一个重要概念,它允许不同的对象通过相同的接口表现出不同的行为,从而实现更加灵活和可扩展的代码结构。多态性有助于降低代码的耦合度,增加代码的可维护性和可扩展性。

在面向对象编程中,多态性通常与继承和接口相关联。通过继承和接口的概念,可以实现多态性的三种形式:编译时多态、运行时多态和参数多态。

  1. 编译时多态(Compile-Time Polymorphism): 也称为静态多态性,发生在编译时期。它通过方法的重载(方法名相同,但参数列表不同)来实现。编译器会根据传递给方法的参数的类型和数量来确定调用哪个重载方法。

编译时多态(函数重载和模板):

#include <iostream>class MathOperations {
public:int add(int a, int b) {return a + b;}double add(double a, double b) {return a + b;}
};template <typename T>
T customAdd(T a, T b) {return a + b;
}int main() {MathOperations math;std::cout << math.add(5, 3) << std::endl;          // 编译时选择 int add(int, int)std::cout << math.add(2.5, 3.7) << std::endl;      // 编译时选择 double add(double, double)std::cout << customAdd(4, 6) << std::endl;         // 编译时选择 customAdd<int>std::cout << customAdd(2.3, 1.7) << std::endl;     // 编译时选择 customAdd<double>return 0;
}
  1. 运行时多态(Runtime Polymorphism): 也称为动态多态性,发生在运行时期。它通过方法的覆盖(子类实现父类的方法)来实现。在运行时,实际调用的方法取决于对象的实际类型。
    运行时多态(虚函数和继承):
#include <iostream>class Shape {
public:virtual void draw() {std::cout << "Drawing a Shape" << std::endl;}
};class Circle : public Shape {
public:void draw() override {std::cout << "Drawing a Circle" << std::endl;}
};class Square : public Shape {
public:void draw() override {std::cout << "Drawing a Square" << std::endl;}
};int main() {Shape* shape1 = new Circle();Shape* shape2 = new Square();shape1->draw(); // 运行时选择 Circle::draw()shape2->draw(); // 运行时选择 Square::draw()delete shape1;delete shape2;return 0;
}
  1. 参数多态(Parametric Polymorphism): 也称为泛型编程,发生在方法或类定义时。它允许在定义方法或类时使用占位符类型,然后在使用时指定具体的类型。这样可以实现通用的方法和类,提高代码的重用性。
class GenericList<T> {private T[] items;void addItem(T item) {// Add item to the list}
}

在Go语言中,多态性主要通过接口来实现。接口定义了一组方法的签名,不关心具体类型,从而允许不同类型实现相同的接口,从而达到多态性的目的。通过使用接口,可以实现运行时多态,因为在运行时根据实际类型来调用相应的方法

编译时多态和运行时多态的差异

编译时多态(Compile-Time Polymorphism)和运行时多态(Runtime Polymorphism)是面向对象编程中两种不同类型的多态性,它们在实现方式和发生的阶段上存在差异。

编译时多态(Compile-Time Polymorphism)

  1. 发生时机:编译时多态发生在编译阶段,即在代码编译为机器代码之前。
  2. 实现方式:编译时多态通过方法的重载(方法名相同,参数列表不同)来实现,编译器根据方法的参数类型和数量来选择合适的重载方法。
  3. 调用解析:方法的选择在编译期间已经确定,不需要在运行时进行动态判断,因此具有较高的执行效率。
  4. 示例:在同一个类中定义多个具有相同方法名但参数不同的方法,编译器在调用时根据传入的参数类型选择对应的方法。

运行时多态(Runtime Polymorphism)

  1. 发生时机:运行时多态发生在程序实际运行的阶段,即在代码被执行时。
  2. 实现方式:运行时多态通过方法的覆盖(子类实现父类的方法)来实现,子类可以对父类方法进行重写,实际调用的方法由对象的实际类型决定。
  3. 调用解析:方法的选择发生在运行时,需要动态地判断对象的实际类型,然后调用相应的方法,因此会引入一定的运行时开销。
  4. 示例:定义一个父类和多个子类,子类重写了父类的方法,然后通过父类引用调用方法,在运行时会根据实际对象类型调用对应的子类方法。

总之,编译时多态和运行时多态都是多态性的体现,但它们在发生的时机、实现方式和调用解析等方面存在差异。编译时多态适用于方法重载的情况,而运行时多态适用于方法覆盖的情况。根据具体的代码需求和性能要求,可以选择合适的多态性实现方式。

go 语言多态性

在 go 语言中多态性有接口实现。当使用Go语言的接口来实现多态性时,一个具体的例子是在处理不同形状的图形时,可以使用一个通用的接口类型来实现绘制操作,从而实现代码重用和灵活性。

假设我们有三种不同的图形:圆形、正方形和三角形,每种图形都有自己的绘制方法。我们可以通过接口来实现多态性,使得这些图形可以被视为同一类型的实例,并且可以通过通用的方法进行绘制。

package mainimport "fmt"// Shape 接口定义了绘制操作
type Shape interface {Draw()
}// Circle 类型表示圆形
type Circle struct {Radius float64
}func (c Circle) Draw() {fmt.Printf("Drawing a circle with radius %.2f\n", c.Radius)
}// Square 类型表示正方形
type Square struct {SideLength float64
}func (s Square) Draw() {fmt.Printf("Drawing a square with side length %.2f\n", s.SideLength)
}// Triangle 类型表示三角形
type Triangle struct {Base   float64Height float64
}func (t Triangle) Draw() {fmt.Printf("Drawing a triangle with base %.2f and height %.2f\n", t.Base, t.Height)
}func main() {shapes := []Shape{Circle{Radius: 2.5},Square{SideLength: 4.0},Triangle{Base: 3.0, Height: 5.0},}for _, shape := range shapes {shape.Draw() // 多态性,根据具体类型调用对应的 Draw 方法}
}

在上面的例子中,我们定义了一个 Shape 接口,其中包含了一个 Draw 方法。然后,我们定义了三种不同的图形类型 CircleSquareTriangle,它们都实现了 Shape 接口的 Draw 方法。在 main 函数中,我们创建了一个包含不同类型图形的切片,并通过遍历切片来调用多态性的 Draw 方法,实现了统一的绘制操作。

这个例子展示了如何通过使用接口实现多态性,从而实现了代码的重用和灵活性。无论是添加新的图形类型还是修改现有图形类型的实现,都不会影响到通用的绘制操作,从而提高了代码的可维护性和扩展性。

相关文章:

多态性说明

多态 多态性多态性类型描述编译时多态和运行时多态的差异go 语言多态性 多态性 多态性类型描述 多态性是面向对象编程中的一个重要概念&#xff0c;它允许不同的对象通过相同的接口表现出不同的行为&#xff0c;从而实现更加灵活和可扩展的代码结构。多态性有助于降低代码的耦…...

2023-08-04 LeetCode每日一题(不同路径 III)

2023-08-04每日一题 一、题目编号 980. 不同路径 III二、题目链接 点击跳转到题目位置 三、题目描述 在二维网格 grid 上&#xff0c;有 4 种类型的方格&#xff1a; 1 表示起始方格。且只有一个起始方格。2 表示结束方格&#xff0c;且只有一个结束方格。0 表示我们可以…...

腾讯云服务器地域怎么选?可用区是什么?

腾讯云服务器地域有什么区别&#xff1f;怎么选择比较好&#xff1f;地域选择就近原则&#xff0c;距离地域越近网络延迟越低&#xff0c;速度越快。关于地域的选择还有很多因素&#xff0c;地域节点选择还要考虑到网络延迟速度方面、内网连接、是否需要备案、不同地域价格因素…...

第一百二十三天学习记录:C++提高:STL-vector容器(下)(黑马教学视频)

vector插入和删除 功能描述&#xff1a; 对vector容器进行插入、删除操作 函数原型&#xff1a; push_back(ele); //尾部插入元素ele pop_back(); //删除最后一个元素 insert(const_iterator pos, ele); //迭代器指向位置pos插入元素ele insert(const_iterator pos, int cou…...

谈谈Spring与字节码生成技术

Spring框架是一个面向企业级Java应用开发的开源框架&#xff0c;它提供了许多功能和特性来简化Java开发过程。字节码生成技术在Spring框架中起着重要的作用&#xff0c;用于实现依赖注入&#xff08;Dependency Injection&#xff09;和面向切面编程&#xff08;Aspect-Oriente…...

Java数组详解 -- 基础知识与常用操作

文章目录 前言一、初识数组1. 数组的定义2. 数组的特点3. 声明和初始化数组4. 默认初始化值 二、访问和操作数组元素1. 数组的索引和范围2. 通过索引访问数组元素3. 修改数组元素的值 三、数组的长度和属性1. 数组的长度计算2. 数组的长度属性3. 数组越界的错误 四、数组的遍历…...

(统计学习方法|李航)第五章 决策树——一二三节:决策树模型与学习,特征选择,决策树的生成,

目录 一&#xff0c;决策树模型与学习 1.决策数模型 2.决策树与if-then规则 3.决策树与条件概率分布 4.决策树学习 二&#xff0c;特征选择 1.特征选择问题 2.信息增益 3.信息增益比 三&#xff0c;决策树的生成 1.ID3算法 2.C4.5的生成算法 一&#xff0c;决策树模型…...

qt lamda表达式及捕获变量列表符号说明及示例

问题描述: 最近发现很多人都喜欢用Lamda表达式了,至于他们到底知不知道自己用的是什么意思,那就另说了。 虽然我个人并不太喜欢,因为很多地方没法像以前信号和槽那样清晰了,而且很多生成UML的软件估计也不支持解析转成对应的序列图啥的。 但是这个lamda写法确实挺方便的…...

第十六章、【Linux】程序管理与SELinux初探

16.1 什么是程序 &#xff08;process&#xff09; 在Linux 系统当中&#xff1a;“触发任何一个事件时&#xff0c;系统都会将他定义成为一个程序&#xff0c;并且给予这个程序一个 ID &#xff0c;称为 PID&#xff0c;同时依据启发这个程序的使用者与相关属性关系&#xff…...

ElasticSearch索引生命周期管理--DELETE

概要 ElasticSearch中的索引生命周期管理&#xff0c;也就是ilm&#xff08;Manage the index lifecycle&#xff09;,是指定了索引在不同周期下的处理策略。ilm 的对象是索引而不是索引中的数据。ilm 包括四个阶段&#xff1a;hot 、warm、cold和delete。hot、warm和cold表示…...

sentinel简单使用

核心demo&#xff1a; 1 引入依赖: <dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-core</artifactId><version>1.8.0</version> </dependency>2 核心代码&#xff1a; 3 限流保护代码&#xff1a;…...

C#小轮子:自动连续Ping网络地址

文章目录 前言Ping代码异步问题 前言 工作中&#xff0c;我们经常用到Ping这个指令&#xff0c;有时候我们需要Ping整个网段来查看这个网段上面有什么设备&#xff0c;哪些Ip地址是通的&#xff0c;这个时候就需要Ping指令 Ping 代码 我这个是批量Ping的代码&#xff0c;而…...

react入门笔记

什么是React? React是一个用于创建用户界面的开源前端javaScript库。它是声明式的、高效的和灵活的&#xff0c;并且他坚持基于组件的方法&#xff0c;这使得我们能够创建可重用的UI组件。 React是一个开源的前端javaScript库&#xff0c;用于构建用户界面或者UI组件。它是由…...

记录--前端重新部署如何通知用户

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 1. 场景 前端构建完上线&#xff0c;用户还停留还在老页面&#xff0c;用户不知道网页重新部署了&#xff0c;跳转页面的时候有时候js连接hash变了导致报错跳不过去&#xff0c;并且用户体验不到新功能…...

WPS的excel表格单元格拖动数字日期等 不自增原因

对着表格中的每个单元格右下角,在变成下图,黑十字后,拖动这个十字.就会在右侧出现一个小窗口. 里面菜单中可以选择按序数增加 但是,如果拖动,发现小窗口菜单不出现.说明这一栏开启了筛选功能.清空筛选条件后,即可恢复自增功能....

2308C++简单异步懒

Lazy Lazy由C20无栈协程实现.一个Lazy闭包一个懒求值的计算任务. 使用Lazy 想用Lazy,需要先#inlude<async_simple/coro/Lazy.h>,再实现返回类型为Lazy<T>的协程函数即可.如: # 包含<简单异步/协程/懒.h>懒<整>任务1(整 x){协中 x;//带有协中的函数…...

Linux常规操作命令

日升时奋斗&#xff0c;日落时自省 目录 1、vim 1.1、工作模式 1.2、末行模式操作相关命令 1.2.1、保存退出操作 1.2.2、查找替换 1.3、输入模式操作相关命令 1.3.1、移动相关命令 1.3.2、删除和剪切命令 1.3.3、复制操作 1.3.4、撤销 2、head 3、tail 4、ps 5、…...

日期切换

组件&#xff1a;<template><div class"time-picker"><el-radio-group size"small" v-model"timeType" change"changePickerType"><el-radio-button label"hour" v-if"isShow">时</el…...

怎么裁剪视频大小尺寸?简单的裁剪方法分享

怎么裁剪视频的画面大小尺寸呢&#xff1f;有时当我们下载下来一段视频&#xff0c;由于视频的画面大小比例不同&#xff0c;会有很多的黑边&#xff0c;我们不管是观看还是进行二次编辑都非常影响体验&#xff0c;而调整视频画面比例以适应观众的设备或平台&#xff0c;比如将…...

智慧工地源码,Spring Cloud+ Vue+UniApp开发,微服务架构

智慧工地源码&#xff0c;智慧工地云平台源码 智慧工地APP源码 智慧工地的核心是数字化&#xff0c;它通过传感器、监控设备、智能终端等技术手段&#xff0c;实现对工地各个环节的实时数据采集和传输&#xff0c;如环境温度、湿度、噪音等数据信息&#xff0c;将数据汇集到云…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...