C++ 抽象类和接口 详解
目录
- 0 引言
- 1 抽象类
- 2 接口
- 2.1 Java与C++接口的区别

- 🙋♂️ 作者:海码007
- 📜 专栏:C++专栏
- 💥 标题:C++ 抽象类和接口 详解
- ❣️ 寄语:书到用时方恨少,事非经过不知难!
- 🎈 最后:文章作者技术和水平有限,如果文中出现错误,希望大家能指正
0 引言
随着编程的深入,总是会听到不少抽象类,接口等词汇。但是其实很多有都在混淆概念,甚至是乱用这些定义。接下来就和我一起探讨一下C++中的抽象类和接口的区别,以及拓展一下 C++ 和 Java 的区别。
1 抽象类
在C++中,抽象类(Abstract Class)是包含至少一个纯虚函数的类。抽象类不能被实例化,只能被用作其他类的基类。纯虚函数是一种在基类中声明但没有提供实际实现的虚函数,它的存在要求任何继承自这个基类的派生类都必须提供实际的实现(如果不实现,那基类仍然是抽象类)。这样的设计允许抽象类提供一个接口,而具体的实现则由派生类完成。
在C++中,定义一个抽象类的典型方式如下:
class AbstractClass {
public:// 纯虚函数,使得AbstractClass成为抽象类virtual void pureVirtualFunction() = 0;// 虚析构函数(防止派生类析构时,不调用派生类的析构函数)virtual ~AbstractClass() {}// 普通成员函数void concreteFunction() {// 可以包含具体实现// 但通常抽象类中也包含一些纯虚函数,以强制派生类提供实现}// 普通成员变量int data;
};
在这个例子中,pureVirtualFunction是一个纯虚函数,因此AbstractClass就成为了抽象类。由于抽象类不能被实例化,你不能创建AbstractClass的对象。它主要用于作为其他类的基类,要求派生类必须提供纯虚函数的实际实现。
具体的派生类可以这样实现:
class ConcreteClass : public AbstractClass {
public:// 实现纯虚函数void pureVirtualFunction() override {// 具体的实现}
};
注意,在派生类中必须提供对抽象类中纯虚函数的实现,否则派生类也会变成抽象类,无法被实例化。
2 接口
在C++中接口就是一种特殊的抽象类,接口中只包括纯虚函数。
在C++中,与一些其他编程语言(如Java和C#)不同,C++没有显式的接口关键字。然而,C++中可以通过抽象类和纯虚函数来实现接口的概念。
在C++中,接口通常是通过抽象类来定义的,该抽象类包含纯虚函数(没有实现),而派生类则负责提供这些纯虚函数的具体实现。这种方式类似于其他语言中的接口定义。
下面是一个使用抽象类和纯虚函数实现接口的简单示例:
#include <iostream>// 定义接口(抽象类)
class Interface {
public:// 纯虚函数,相当于接口中的方法声明virtual void doSomething() = 0;
};// 不能在接口中包含普通成员函数
// 下面的代码会导致编译错误
/*
class Interface {
public:virtual void doSomething() = 0;void commonFunction() {std::cout << "Common function in Interface." << std::endl;}
};
*/// 实现接口的具体类
class ConcreteClass : public Interface {
public:// 提供接口中纯虚函数的具体实现void doSomething() override {std::cout << "Doing something in ConcreteClass." << std::endl;}
};int main() {// 通过接口指针调用实现类的方法Interface* obj = new ConcreteClass();obj->doSomething();delete obj;return 0;
}
2.1 Java与C++接口的区别
Java和C++在接口(interface)方面存在一些显著的区别。了解这些区别对于使用这两种语言进行编程是很重要的。以下是主要的区别点:
-
定义和用途:
- Java接口:Java中的接口是一个完全抽象的类,只能包含抽象方法和常量。接口用于声明一组方法,然后由其他类实现。Java接口是实现多继承的一种方式。
- C++接口:C++没有内置的接口关键字,但可以通过创建纯虚函数(pure virtual functions)的抽象类来模拟接口。这些类不能被实例化,只能被其他类继承。
-
实现方法:
- Java:在Java中,类可以实现多个接口。使用
interface关键字来实现接口,并且必须实现接口中的所有方法。 - C++:C++中的类通过继承抽象类来实现接口,并且必须实现所有的纯虚函数。C++支持多重继承,因此一个类可以继承多个抽象类。
- Java:在Java中,类可以实现多个接口。使用
-
默认方法:
- Java:从Java 8开始,接口可以包含默认方法(default methods)。这些方法不是抽象的,可以有自己的实现。这允许在不影响实现该接口的类的情况下添加新功能。
- C++:C++的抽象类可以包含已经实现的成员函数,这在某种程度上类似于Java的默认方法。
-
属性:
- Java:Java接口中可以声明常量,但不能包含实例字段。所有定义在接口中的变量默认都是
public static final的。 - C++:C++中的抽象类可以包含成员变量和常量。
- Java:Java接口中可以声明常量,但不能包含实例字段。所有定义在接口中的变量默认都是
-
多重继承和菱形问题(Diamond Problem):
- Java:由于Java不支持从多个类继承,因此使用接口来实现多重继承。Java接口不会导致菱形问题,因为它们不具备实现继承。
- C++:C++支持从多个类继承,但这可能导致菱形问题。当两个父类都继承自同一个祖先类时,子类可能会从每个父类继承相同的祖先类的两个副本。
这些差异反映了Java和C++设计哲学的不同:Java更注重简洁和安全,而C++提供了更高的灵活性和控制权,但也带来了更复杂的语言特性和潜在的错误风险。
// 定义一个接口
interface Vehicle {void drive();int getNumberOfWheels();
}// 一个类实现接口
class Car implements Vehicle {public void drive() {// 实现drive方法的具体逻辑}public int getNumberOfWheels() {// 返回轮子数量return 4;}
}
相关文章:
C++ 抽象类和接口 详解
目录 0 引言1 抽象类2 接口2.1 Java与C接口的区别 🙋♂️ 作者:海码007📜 专栏:C专栏💥 标题:C 抽象类和接口 详解❣️ 寄语:书到用时方恨少,事非经过不知难!…...
【Linux】awk 使用
awk 输出 // 打印所有列 $ awk {print $0} file // 打印第一列 $ awk {print $1} file // 打印第一和第三列 $ awk {print $1, $3} file // 打印第三列和第一列,注意先后顺序 $ cat file | awk {print $3, $1} …...
LeetCode力扣每日一题(Java):9、回文数
一、题目 二、解题思路 1、我的思路 当x<0时,x一定不是回文数,直接返回false 当x>0且x<10时,x一定是回文数,直接返回true x>10时,先将x转为字符串。将数字转成字符串方法挺多的,以下是&…...
WPF前端实现人脸扫描动画效果
前言 本章实现的效果主要通过OpacityMask与LinearGradientBrush(径向渐变) 的组合应用来实现。最终实现效果如下: LinearGradientBrush线性渐变画刷 LinearGradientBrush其实很简单,我们只需要关注5个属性,使用这5个属性你就可以完成这个画刷几乎所有的变化。 属性介…...
更改AndroidStudio模拟器位置
C盘何等的珍贵,可是好多工具,软件非得默认安装在C盘。。导致C盘越来越紧张。。 在日常使用过程中,安装任何软件都会将其安装到非系统盘下,Android模拟器也不能例外。保护好C盘也是日常一个良好的习惯。 Android AVD默认路径&…...
Dash 协议介绍
<?xml version"1.0" encoding"utf-8"?> <MPD xmlns"urn:mpeg:dash:schema:mpd:2011" minBufferTime"PT1.5S" type"static" mediaPresentationDuration"PT0H1M0.3S" maxSegmentDuration"PT0H0M2.0…...
RabbitMQ的消息发送和接收机制
所有 MQ 产品从模型抽象上来说都是一样的过程: 消费者(consumer)订阅某个队列。生产者(producer)创建消息,然后发布到队列(queue)中,最后将消息发送到监听的消费者。 上…...
记录111
在两台 RHEL 8 服务器上搭建 PostgreSQL 和 pgpool-II 环境涉及到安装 PostgreSQL、配置流复制(Streaming Replication)以及安装和配置 pgpool-II。以下是详细的步骤: ### 准备工作 1. **获取服务器**:确保你有两台运行 RHEL 8 的…...
振动和震动的区别?
问题描述:振动和震动的区别? 问题解决: 震动(Oscillation): 特点: 随机的、突发的、不经常的、无规律的运动。例子: 地壳震动、消息震动全国,强调的是运动的力度或幅度&…...
3DMM模型
目录 BFMBFM_200901_MorphableModel.matexp_pca.bintopology_info.npyexp_info.npy BFM BFM_2009 01_MorphableModel.mat from scipy.io import loadmat original_BFM loadmat("01_MorphableModel.mat") # dict_keys: [__header__, __version__, __globals__, # …...
Python 3 使用 write()、writelines() 函数写入文件
1 使用 write() 函数,将字符串(或字节串,仅适用写入二进制文件中)写入文件中。 with open(example.txt,w,encodingutf-8) as f:f.write(春夜喜雨\n)f.write(杜甫 [唐代]\n)f.write(好雨知时节,当春乃发生。\n)f.write(…...
鸿蒙(HarmonyOS)应用开发——管理组件状态
状态管理 在应用中,界面通常都是动态的。 #mermaid-svg-DrPNsglFkyLqn7Lw {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-DrPNsglFkyLqn7Lw .error-icon{fill:#552222;}#mermaid-svg-DrPNsglFkyLqn7Lw …...
倚天屠龙:Github Copilot vs Cursor
武林至尊,宝刀屠龙。号令天下,莫敢不从。倚天不出,谁与争锋! 作为开发人员吃饭的家伙,一款好的开发工具对开发人员的帮助是无法估量的。还记得在学校读书的时候,当时流行CS架构的RAD,Delphi和V…...
【web安全】RCE漏洞原理
前言 菜某的笔记总结,如有错误请指正。 RCE漏洞介绍 简而言之,就是代码中使用了可以把字符串当做代码执行的函数,但是又没有对用户的输入内容做到充分的过滤,导致可以被远程执行一些命令。 RCE漏洞的分类 RCE漏洞分为代码执行…...
EI论文复现:基于组合双向拍卖的共享储能机制研究程序代码!
本程序参考EI期刊论文《基于组合双向拍卖的共享储能机制研究》,文中的组合双向拍卖交易机制较为新颖,本质上属于博弈范畴,共享储能是目前的研究热点,牵涉到共享储能参与者的投标策略和收益函数,文中所提模型可为电力市…...
ThinkPHP 5 中,你可以使用定时任务调度器(TaskScheduler)来执行其他定时任务
在 ThinkPHP 5 中,你可以使用定时任务调度器(TaskScheduler)来执行其他定时任务。以下是一个示例代码,演示如何在一个定时任务中执行另一个定时任务: 首先,你需要创建一个继承自 think\console\Command 的…...
mysql:免费的GUI客户端工具推荐并介绍常用的操作
给大家推荐几个常用的 mysql 数据库客户端 sequel-pro sequel-ace 官网下载地址 免费 sequel-ace 可以理解为 Sequel Pro 的升级版,由于Sequel Pro官方不维护了,特别是对 MySQL 8.0 支持不好,所以现在由社区维护了新分支 sequel-ace&#x…...
[Unity数据管理]自定义菜单创建Unity内部数据表(ScriptableObject)
Unity 在开发的时候如果数据量比较大,或者一部分数据需要存在云端,那么就需要一些数据库 轻量型到大型的包括: 数组-内存存储读取 列表-内存存储读取 List<T> tList new List<T>(); XML-硬盘存储读取 JSON-硬盘存储读取 …...
使用JAVA语言写一个排队叫号的小程序
以下是一个简单的排队叫号的小程序,使用JAVA语言实现。 import java.util.LinkedList; import java.util.Queue; import java.util.Scanner;public class NumberingSystem {public static void main(String[] args) {Queue<String> queue new LinkedList<…...
openGauss学习笔记-140 openGauss 数据库运维-例行维护-例行维护表
文章目录 openGauss学习笔记-140 openGauss 数据库运维-例行维护-例行维护表140.1 相关概念140.2 操作步骤140.3 维护建议 openGauss学习笔记-140 openGauss 数据库运维-例行维护-例行维护表 为了保证数据库的有效运行,数据库必须在插入/删除操作后,基于…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
Linux中《基础IO》详细介绍
目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...
沙箱虚拟化技术虚拟机容器之间的关系详解
问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西,但是如果把三者放在一起,它们之间到底什么关系?又有什么联系呢?我不是很明白!!! 就比如说: 沙箱&#…...
第八部分:阶段项目 6:构建 React 前端应用
现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...
ArcGIS Pro+ArcGIS给你的地图加上北回归线!
今天来看ArcGIS Pro和ArcGIS中如何给制作的中国地图或者其他大范围地图加上北回归线。 我们将在ArcGIS Pro和ArcGIS中一同介绍。 1 ArcGIS Pro中设置北回归线 1、在ArcGIS Pro中初步设置好经纬格网等,设置经线、纬线都以10间隔显示。 2、需要插入背会归线…...
