C++之封装继承和多态
C++中非常重要的概念,尤其是相对于C语言而言,也是其具有如此高的工程使用性的重要原因。
封装
所谓封装是将某些东西隐藏起来,让外界无法直接使用,而必须通过某些特定的方式才能访问。也即是,将抽象得到的数据和行为(类似于属性和方法)结合构成一个有机整体,将数据与操作数据的函数构成类,其中数据和函数都是类的成员。
其目的是将对象的使用者和设计者隔离开来,提高软件的可维护性和可修改性,使用者不必了解具体的实现细节而只是通过外部接口及特定的访问权限使用类成员,从而增强了安全性且简化了编程,也使得不同类之间的相互影响降到最低。
一个类的成员有三种访问权限可以选择
- public 所有人均可访问
- private 只有当前类中成员函数可以访问
- protected 只有当前类中和当前类的派生类中的成员函数可以访问
如果没有显示声明,class中的成员数据或成员函数默认访问权限是private,struct中默认访问权限是public
继承
指的是新类从已有的类中得到已有的特性。
继承使得子类具有父类的某些数据和函数,而不需要再次编写相同的代码,在继承的同时,子类也可以重新定义某些数据和函数并覆盖父类原有的数据和函数。
与类的成员访问权限相关,继承方式也分为三种:public,private,protected
一般分为单一继承和多重继承,常用的是单一继承,编程简单,可读性好。
需要注意的是class默认是private继承,而struct默认是public继承。
| 父类中的访问权限 | 继承方式 | 子类中的访问权限 |
| public | public | public |
| private | No access | |
| protected | protected | |
| public | private | private |
| private | No access | |
| protected | private | |
| public | protected | protected |
| private | No access | |
| protected | protected |
子类会继承父类/基类除构造函数和析构函数以外的成员函数,一般析构函数定义为虚函数,否则的话析构时只会调用父类/基类中定义的析构函数而不会调用子类/派生类中的析构函数。
多态
父类成员函数前加virtual修饰就变成了虚函数。
纯虚函数就是父类只定义了虚函数而没有实现,则必须在子类中实现。如果子类中没有实现则子类仍为虚类,需要子类的子类去实现纯虚函数,即哪一层子类实现了纯虚函数,哪一层的子类才可以被初始化。纯虚函数相当于一个接口,子类必须实现这个接口才可以使用。
而多态性就是为了接口重用,无论传递过来的是哪个子类的对象,都能调用相应的子类函数。
多态是我们可以用相同的方式处理不同类型的对象,极大地提高了代码的可重复性。
多态性允许将子类类型的指针赋值给父类类型的指针,常通过虚函数来实现。虚函数就是允许子类重新定义的成员函数。
子类重写父类中的虚函数时,即使不用virtual声明,该函数也是虚函数,而父类中必须要有virtual声明。
一个接口,多种方法,多态主要有两种形式。
静态多态
在编译期将函数链接起来,此时即可确定调用哪个函数或模板,静态多态通过重载和模板实现。
在宏多态中,通过定义变量,编译时直接把变量替换,实现宏多态。
- 优点
- 泛型编程,STL,非常便利
- 编译期完成,提高了运行效率
- 具有很强的适配性和松耦合性
- 缺点
- 使得编程可读性降低,代码调试困难
- 无法实现木板的分离编译,工程量大时编译时间较长
- 无法处理异质对象集合
动态多态
在程序运行期间才能确定调用哪个函数或实现。父类指针或引用能够指向子类对象,调用子类的函数,所以在编译时无法确定调用哪个函数。
例如在父类中写一个虚函数,子类中进行重写,用一个指向父类的指针调用虚函数,实际上会调用在子类中重写的虚函数。
运行期多态的实现依赖于虚函数机制,当某个类声明了虚函数时,编译器将为该类对象安插一个虚函数表指针,并为该类设置一个唯一的虚函数表,表中存放该类虚函数的入口地址,运行期间通过虚函数表指针与虚函数表去确定该类虚函数的真正实现。
- 优点
- 面向对象设计中非常重要的特性,对客观世界直觉的认识。
- 可以处理同一继承体系下的异质类集合
vector<Animal*> anims;
Animal *anim1 = new Dog;
Animal *anim2 = new Cat; // 处理异质类集合实例
anims.push_back(anim1);
anims.push_back(anim2);
- 缺点
- 运行期间进行虚函数绑定,增加了程序运行开销
- 庞大的类继承层次,对接口的修改容易影响类的继承层次
- 虚函数在运行期绑定,编译器无法对其进行优化
C++之封装继承和多态的更多相关文章
- day33 序列类型,绑定方法,类方法,静态方法,封装继承和多态
Python之路,Day20 = 序列类型,绑定方法,类方法,静态方法,封装继承和多态 序列是指有序的队列,重点在"有序". 一.Python中序列的分类 Python中的序列主要 ...
- objective-c自学总结(三)---面向对象的封装,继承与多态
面向对象的三大特性 封装 继承 多态 1.封装: 隐藏属性,方法或实现细节的过程称为封装 信息隐藏,隐藏对象的实现细节,不允许用户看到 将东西包装在一 然后以新的完整形式呈现出来 例如,两种或多种化学 ...
- python 面向对象及封装继承和多态
######装饰器######装饰器的概念 - 装饰器的实现是函数里面嵌套函数;- 装饰器的本质是一个函数, 它可以让其他函数在不需要做任何代码改动的前提下增加额外的功能;- 装饰器需要传递一个函数, ...
- Java的封装继承和多态
封装 定义:属性私有private:get/set 目的 提高程序的安全性,保护数据 隐藏代码的实现细节 统一接口 提高系统的可维护性 代码 public class Student { //名字 p ...
- java封装继承以及多态(含代码)
封装 该露的露,该藏的藏 我们常需设计要追求,"高内聚,低耦合".高内聚就是类的内部数据操作细节自己完成.不允许外部干涉:低耦合:仅暴漏少量的方法给外部使用. 封装(数据的隐藏) ...
- C++学习笔记 封装 继承 多态 重写 重载 重定义
C++ 三大特性 封装,继承,多态 封装 定义:封装就是将抽象得到的数据和行为相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成类,其中数据和函数都是类的成员,目的在于将对 ...
- OC的封装、继承与多态
面向对象有三大特征:封装.继承和多态. 一.封装 封装是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问.简而言之,信息隐藏,隐 ...
- 2、C#面向对象:封装、继承、多态、String、集合、文件(上)
面向对象封装 一.面向对象概念 面向过程:面向的是完成一件事情的过程,强调的是完成这件事情的动作. 面向对象:找个对象帮你完成这件事情. 二.面向对象封装 把方法进行封装,隐藏实现细节,外部直接调用. ...
- java面向对象(封装-继承-多态)
框架图 理解面向对象 面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程强调的是功能行为 面向对象将功能封装进对象,强调具备了功能的对象. 面向对象是基于面向过程的. 面向对象的特点 ...
随机推荐
- 常见的RuntimeException报错原因
对于RuntimeException 做java开发的朋友想必不会陌生,可以用于事物的回滚操作.异常类型也有很多种,写这篇文章主要是为了总结自己开发中遇到的一些异常类型 以便帮助大家遇到相应的报错找不 ...
- java虚拟机栈 相关操作
针对JVM虚拟栈 和栈帧的操作 虚拟机栈: 栈元素是栈帧.方法调用,栈帧入栈,反之出栈. 栈帧:一个方法的运行空间. 1.局部变量表:方法定义的局部变量.方法的参数存在该表. 实例方法中有个隐含参数“ ...
- 【同步工具类】CountDownLatch闭锁任务同步
[同步工具类]CountDownLatch闭锁任务同步 转载:https://www.cnblogs.com/yangchongxing/p/9214284.html 打过dota的同学都知道,多人一 ...
- 201871010119-帖佼佼《面向对象程序设计(java)》第一周学习总结
项目 内容 这个作业属于哪个课程 <任课教师博客主页链接> https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 <作业链接地址> ...
- java8-StreamAPI之collection归约操作
一说明 经过前一篇的StreamAPI学习,基本的流操作我相信大家都熟练于心了,那么今天是要详细解析一下收集器(collect)这么API 前提要区分,collect(StreamAPI)与coll ...
- ajax添加请求头(添加Authorization字段)
我们在发AJAX请求的时候可能会需要自定义请求头,在jQuery的$.ajax()方法中提供了beforeSend属性方便我们进行此操作. beforeSend: function(request) ...
- ZedGraph的曲线的LineItem对象的Tag属性存储信息进而在鼠标悬浮时进行显示
场景 Winform中设置ZedGraph鼠标悬浮显示距离最近曲线上的点的坐标值和X轴与Y轴的标题: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article ...
- Linux下修改MySQL数据库数据文件路径
使用rpm安装方式安装完MySQL数据库后,数据文件的默认路径为/var/lib/mysql,然而根目录并不适合用于存储数据文件. 原路径:/var/lib/mysql 目标路径:/home/mysq ...
- delete和Vue.$delete删除数组的区别
delete delete只是被删除的元素变成了 empty/undefined ,其他的元素的键值对应关系还是不变. Vue.$delete 直接删除了数组中元素,数组的键值对应关系发生相应变化 例 ...
- Windows下安装和破解redis desktopmanager 2019.4
redis可视化客户端工具:redis desktop manager 破解版链接:https://www.52pojie.cn/thread-1042770-1-1.html redis deskt ...