什么是OOP思想?封装、继承、多态

参考:

https://blog.csdn.net/qq_37934101/article/details/81365449 
https://www.cnblogs.com/cxq0017/p/6490945.html

https://blog.csdn.net/alidada_blog/article/details/80734900 

https://blog.csdn.net/stay_the_course/article/details/55259801

 

OOP思想的核心:封装,继承,多态

达到了软件工程的三个目标:重用性、灵活性、拓展性

对现实世界的事物进行抽象,包括事物的成员变量和成员方法。因此在程序中对事物的描述就必须符合真实情况,同时符合人类的正常思维习惯。因此,如果我们需要在计算机中描述这类事物,就必须把该事物的所有特点都包含起来,用成员变量描述事物的基本属性,例如人的基本属性:身高、体重、年龄、性别等。这样就可以描述一个“静态”的人,所谓静态的人就是不为他赋予任何成员方法。但是这样就不符合现实。所以我们需要用成员方法来描述人的活动,比如:吃饭,洗澡,睡觉等。

对象对抽象事物的具体表示,使其具有自身的特点。对象就是一个类的具体化,类好比一个大的集合,而对象则是类的具体化,也是实例化。类是泛指,而对象是特指。虽然人都有身高、体重、年龄、性别,但是具体到某个人身上的时候也不一样。例如老人和小孩的年龄就不同。所以在从类到对象是我们把现实事物进行计算机描述的过程,也是从抽象到具体的过程,符合我们真实思维的逻辑。

 

封装:所谓封装就是将某些东西包装盒隐藏起来,让外界无法直接使用只能通过某些特定的方式才能访问。封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而是通过外部接口以及特定的访问权限来使用类的成员。

例如:下面是一个动物类,将数据和功能封装起来。

class Animal
{
public://这是公共成员,外部的接口;
    void AnimalName(String name);
    void ShowAnimalName();
private://私有成员,外部无法访问到
    String name;
};

因此我们可以通过封装使一部分成员充当类与外部的接口,而将其他的成员隐藏起来,这样就限制了外部对成员的访问,也使不同类之间的相互影响度降低。

继承:继承是指一个对象直接使用另一个对象的属性和方法。例如:若把动物堪称一个实体,他可以分为很多个子实体如:猫、狗等等。这些子实体都具有动物的特性,因此,动物使他们的“父亲”,而这些子实体是动物的“孩子”。

也就是说如果一个类B继承自另一个类A,就把这个类B称为类A的子类,而把A称为B的父类。继承可以是的子类具有父亲的各种属性和方法,而不需要再次编写相同的代码,在令子类继承父类的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类的原有属性和方法,使其获得和父类不同的功能。

多态

多态按字面的意思就是多种形态,相同的方法调用,但是有不同的实现方式。多态性可以简单地概括为“一个接口,多种方法”。 
C++有两种多态形式:

  • 静态多态
  • 动态多态

静态多态
静态多态:也称为编译期间的多态,编译器在编译期间完成的,编译器根据函数实参的类型(可能会进行隐式类型转换),可推断出要调用哪个函数,如果有对应的函数就调用该函数,否则出现编译错误。 

静态多态有两种实现方式:

函数重载:包括普通函数的重载和成员函数的重载
函数模板的使用

函数重载是一种特殊情况,C++允许在同一作用域中声明几个类似的同名函数,这些同名函数的形参列表(参数个数,类型,顺序)必须不同,常用来处理实现功能类似数据类型不同的问题。

在C++中不仅函数可以重载,运算符也可以重载。例如:

运算符<<,>>。既可以做移位运算符,也可以做输出,输入运算符。

注意:重载函数的参数个数,参数类型或参数顺序三者中必须有一个不同

 

函数重载的规则:

  • 函数名称必须相同。
  • 参数列表必须不同(个数不同、类型不同、参数排列顺序不同等)。
  • 函数的返回类型可以相同也可以不相同。
  • 仅仅返回类型不同不足以成为函数的重载。

函数重载的作用

重载函数通常用来在同一个作用域内 用同一个函数名 命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处。

函数模板

C++中,模板分为函数模板和类模板。函数模板用来生成函数的,类模板则是用来生成类的。

函数模板的写法如下:

template<class 类型参数1,class 类型参数2,……>
返回值类型 模板名(形参表)
{
    函数体;
}

//其中class关键字也可以用typename关键字替换

template<typename 类型参数1,typename 类型参数2,……>

例如下面的函数:

#include <stdio.h>
#include <iostream>
using namespace std;

template<typename T>

void swap(T x,T y)
{
    T tmp=x;
    x=y;
    y=tmp;
}

int main()
{
    int n=1,m=2;
    swap(n,m);//编译器自动生成void swap(int &,int &)函数
    double a=1.5,b=2.4;
    swap(a,b);//编译器自动生成void swap(double &,double &)函数
    return 0;
}

在编译器编译到swap(n,m);时候编译器就自动用int替换swap模板中的T。同理在编译到swap(a,b);时候用double替换模板函数中的T。

动态多态则是利用虚函数实现了运行时的多态,也就是说在系统编译的时候并不知道程序将要调用哪一个函数,只有在运行到这里的时候才能确定接下来会跳转到哪一个函数的栈帧。

在说动态多态之前我们先来看一下什么是虚函数,虚函数就是在基类中声明该函数是虚拟的(在函数之前加virtual关键字),然后在子类中正式的定义(子类中的该函数的函数名,返回值,函数参数个数,参数类型,全都与基类的所声明的虚函数相同,此时才能称为重写,才符合虚函数,否则就是函数的重载),再定义一个指向基类对象的指针,然后使该指针指向由该基类派生的子类对象,再然后用这个指针来调用改虚函数,就能实现动态多态。

 虚函数表
    包含虚函数的类才会有虚函数表, 同属于一个类的对象共享虚函数表, 但是有各自的_vptr.
    虚函数表实质是一个指针数组,里面存的是虚函数的函数指针。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值