C++基础——面向对象的三大特性:封装、继承、多态

总学习目录
在这里插入图片描述

封装

定义:
封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全。数据封装引申出了另一个重要的 OOP 概念,即数据隐藏。
数据封装是一种把数据和操作数据的函数捆绑在一起的机制,数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制。
C++ 通过创建类来支持封装和数据隐藏(public、protected、private)。我们已经知道,类包含私有成员(private)、保护成员(protected)和公有成员(public)成员。默认情况下,在类中定义的所有项目都是私有的。例如:

功能:
把客观事务封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的行进信息隐藏,公共数据用public修饰,而不希望被访问的数据或方法采用private修饰,private类型的数据可以通过类里面的函数进行return访问,这样就可以保证了数据不被修改,又可以读取到数据的值。
把一个类定义为另一个类的友元类,会暴露实现细节,从而降低了封装性。理想的做法是尽可能地对外隐藏每个类的实现细节。
友元类
友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。
关于友元类的注意事项:
(1) 友元关系不能被继承。
(2) 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
(3) 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明。

class A
{
public:
    friend class C;                         //这是友元类的声明
private:
    int data;
};

class C             //友元类定义,为了访问类A中的成员
{
public:
    int change_data(int x, A &a) {
     a.data = x; 
     cout<<a.data<<endl;
     }
};

继承

定义:
让某种类型对象获得另一个类型对象的属性和方法
功能:
实现代码复用,可以使用现有类的所有功能,并且无需重新编写原来的类的情况下对功能进行拓展。
继承方式:
1、实现继承:
指定基类的属性和方法而不用做其他事情。

  1. public继承方式
    基类中所有 public 成员在派生类中为 public 属性;
    基类中所有 protected 成员在派生类中为 protected 属性;
    基类中所有 private 成员在派生类中不能使用。

  2. protected继承方式
    基类中的所有 public 成员在派生类中为 protected 属性;
    基类中的所有 protected 成员在派生类中为 protected 属性;
    基类中的所有 private 成员在派生类中不能使用。

  3. private继承方式
    基类中的所有 public 成员在派生类中均为 private 属性;
    基类中的所有 protected 成员在派生类中均为 private 属性;
    基类中的所有 private 成员在派生类中不能使用。

下表汇总了不同继承方式对不同属性的成员的影响结果

继承方式/基类成员public成员protected成员private成员
public继承publicprotected不可见
protected继承protectedprotected不可见
private继承privateprivate不可见

2、接口继承:
只使用属性和方法的名称,但是子类必须提供实现的功能
接口继承,就是派生类只继承函数的接口,也就是声明;而实现继承,就是派生类同时继承函数的接口和实现。
虚函数:
虚函数是指一个类中你希望重载的成员函数,当你用一个基类指针或引用指向一个继承类对象的时候,你调用一个虚函数,实际调用的是继承类的版本。——MSDN
虚函数用来表现基类和派生类的成员函数之间的一种关系.
虚函数的定义在基类中进行,在需要定义为虚函数的成员函数的声明前冠以关键字 virtual.
基类中的某个成员函数被声明为虚函数后,此虚函数就可以在一个或多个派生类中被重新定义.
在派生类中重新定义时,其函数原型,包括返回类型,函数名,参数个数,参数类型及参数的先后顺序,都必须与基类中的原型完全相同。
虚函数是重载的一种表现形式,是一种动态的重载方式.

纯虚函数:
在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加 =0。
任何用纯虚函数派生的类,都要自己提供该函数的具体实现。
定义纯虚函数
virtual void fun(void) = 0;//=0表示纯虚函数
非虚函数:
一般成员函数,无virtual关键字修饰。
纯虚类:
只要有一个纯虚函数。就称为纯虚类。
纯虚函数一般是在不方便具体实现此函数的情况下使用。也就是说基类无法为继承类规定一个统一的缺省操作,但继承类又必须含有这个函数接口,并对其分别实现。但是,在C++中,我们是可以为纯虚函数提供定义的,只不过这种定义对继承类来说没有特定的意义。因为继承类仍然要根据各自需要实现函数。
通俗说,纯虚函数就是要求其继承类必须含有该函数接口,并对其进行实现。是对继承类的一种接口实现要求,但并不提供缺省操作,各个继承类必须分别实现自己的操作。
声明非纯虚函数( impure virtual )的目的是让继承类继承该函数的接口和缺省实现。
与纯虚函数唯一的不同就是其为继承类提供了缺省操作,继承类可以不实现自己的操作而采用基类提供的默认操作。
声明非虚函数( non-virtual )的目的是为了令继承类继承函数接口及一份强制性实现。
相对于虚函数来说,非虚函数对继承类要求的更为严格,继承类不仅要继承函数接口,而且也要继承函数实现。也就是为继承类定义了一种行为。

关于继承还可以看这一篇博客
**3、可视继承:**子类使用基类的外观和实现代码的能力

多态

多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作.
多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单一句话:允许将子类类型的指针赋值给父类类型的指针
实现多态有二种方式:覆盖(override),重载(overload)。

**覆盖:**是指子类重新定义父类的虚函数的做法。
**重载:**是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)

多态的优点

  1. 消除类型之间的耦合关系
  2. 可替换性
  3. 可扩充性
  4. 接口性
  5. 灵活性
  6. 简化性

多态存在的三个必要条件
1.继承
2.重写
3.父类引用指向子类对象
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

多态的好处:
可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。

OO开发范式大致为:划分对象→抽象类→将类组织成为层次化结构(继承和合成) →用类与实例进行设计和实现几个阶段。

面向对象五大原则:

单一职责原则SRP(Single Responsibility Principle):
是指一个类的功能要单一,不能包罗万象。如同一个人一样,分配的工作不能太多,否则一天到晚虽然忙忙碌碌的,但效率却高不起来。

开放封闭原则OCP(Open-Close Principle):
一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的。比如:一个网络模块,原来只服务端功能,而现在要加入客户端功能,那么应当在不用修改服务端功能代码的前提下,就能够增加客户端功能的实现代码,这要求在设计之初,就应当将服务端和客户端分开,公共部分抽象出来。

里式替换原则LSP(the Liskov Substitution Principle LSP):
子类应当可以替换父类并出现在父类能够出现的任何地方。比如:公司搞年度晚会,所有员工可以参加抽奖,那么不管是老员工还是新员工,也不管是总部员工还是外派员工,都应当可以参加抽奖,否则这公司就不和谐了。

依赖倒置原则DIP(the Dependency Inversion Principle DIP):
具体依赖抽象,上层依赖下层。假设B是较A低的模块,但B需要使用到A的功能,这个时候,B不应当直接使用A中的具体类: 而应当由B定义一抽象接口,并由A来实现这个抽象接口,B只使用这个抽象接口:这样就达到了依赖倒置的目的,B也解除了对A的依赖,反过来是A依赖于B定义的抽象接口。通过上层模块难以避免依赖下层模块,假如B也直接依赖A的实现,那么就可能 造成循环依赖。一个常见的问题就是编译A模块时需要直接包含到B模块的cpp文件,而编译B时同样要直接包含到A的cpp文件。

接口分离原则ISP(the Interface Segregation Principle ISP):
模块间要通过抽象接口隔离开,而不是通过具体的类强耦合起来

参考:
菜鸟教程
https://blog.csdn.net/ljinddlj/article/details/1922189
https://www.cnblogs.com/pengthrree/p/13099245.html#:~:text=%E5%8F%AF%E8%A7%86%E7%BB%A7%E6%89%BF%E6%98%AF%E6%8C%87%E5%AD%90%E7%AA%97,%E5%AE%9E%E7%8E%B0%E4%BB%A3%E7%A0%81%E7%9A%84%E8%83%BD%E5%8A%9B%E3%80%82

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VoladorL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值