美文网首页
18 类和对象--多态

18 类和对象--多态

作者: ca8519be679b | 来源:发表于2020-11-05 22:49 被阅读0次

我们知道类的3大特性是封装,继承,多态。前2个将差不多了,多态其实也不难。

多态的基本概念

多态分为静态多态和动态多态

函数重载和运算符重载属于静态多态,复用函数名

动态多态是派生类和虚函数实现运行时多态

区别:

静态多态编译时绑定函数地址,而动态多态是运行时确认函数地址(动态比静态多)

1

我们为了理解动态多态,先写一个最简单的,动物有叫的方法,猫继承,重写了方法,注意是重写,不是重载,比重载要求严格是返回值也必须一样。我们编写Animal的引用给speak方法,里面调用shout方法,我们在测试方法里将Cat对象传入,注意C++里是允许将父类引用或者指针指向子类的,这时我们传入了猫,你会以为是猫叫,结果却是动物叫,是类型限制了么,我传入了cat对象。其实这就是静态多态,已经预先定好了内存的位置。所以不管传什么子类都是调用的动物类方法。

2

我们可以把继承变成静态继承,就是将父类方法变成虚函数,而虚函数就是函数前加上virtual,子类cat继承后方法可以不写virtual,写上也没错,如图,就变成运行时调用,这样就实现了猫在叫。

总结,动态多态得有继承关系,子类要重写父类的虚函数,子类的virtual可以不写。动态多态的使用是父类的引用或指针指向子类的对象

3

当我们给Animal定义虚函数时,如上图,其内部就会有个vfptr虚函数指针,指针指向其vftable虚函数表,函数表内记录的是虚函数的地址。

4

如果Cat只是继承,没有重写,则会把虚函数指针继承,同时把父类的虚函数表继承,里面的是动物的函数地址。

5

当Cat重写后,虚函数表就替换成了自己的方法的地址。当我们使用多态方式调用,即父类指针指向时,还是去依据指针指向虚函数表,但是指向变了,这就是多态的原理

6

当然还是可以通过vs命令行去看结构。

多态案例

为什么使用多态,组织结构清晰,可读性强,便于前期和后期的扩展以及维护,尽可能满足对修改关闭对扩展开放的原则

7

如上,我们一般如果自己写一个计算器类,可能会考虑将每个计算方法都添加到类里,但是哪天再添加就需要修改他,而如果我们只定义一个基类,对计算结果留一个接口,然后使用各种类去实现它,然后就可以实现多态的调用,我们这里使用的多态的指针的引用。因为是new出来的空间,所以需要我们手动去释放它,结束要delete掉

纯虚函数和抽象类

我们之前多态虚函数,也写了动物类的shout函数内容,计算器类也写了返回0,其实很多时候我们并不需要这个父类去实例化,所以父类的虚函数定义什么内容就无意义,这时候我们就需要使用什么都没有内容的纯虚函数,而使用了纯虚函数的类叫做抽象类,抽象类是不允许实例化的,也不允许在堆区占用空间,而子类如果不多态重写纯虚函数,则其也是抽象类,直到重写了虚函数为止。

定义纯虚函数的格式   virtual 函数名(参数列表)=0;  这里并不需要函数内容。只等着子类去实现注意有=0及分号

8

如上,我们尝试去实例化一个抽象类,是不可以的

9

如上,我们子类没有重写虚函数,也是抽象类,同样不让实例

10

当我们重写了抽象类的方法,就可以实例化,也能调用方法,因为这个方法有意义

虚析构和纯虚析构

11

首先先来个上面的代码,我们猫继承动物类,分别写出构造和析构打印,将子类继成抽象类,同时使用多态写法指针接收对象,用完需要删除指针,可以看到多态写法并没有执行Cat的析构。如果我们给Cat开辟堆区的属性,那就无法被释放掉,这时我们就可以使用虚析构,就是在父类的析构方法加上virtual关键字,就会实现调用cat析构

12

如上,我们给cat定义了堆区指向的指针,因为我们要析构时释放,所以需要加上经常写的释放语句,但是这里需要给父类的析构加上virtual关键字,这样子类的析构就会在多态的情况下也会被执行。

纯虚析构当然你会简单的以为就是virtual ~父类名()=0;但是如果这么写是不行的,因为父类的析构不被实例化,不能被调用,如果父类开辟了堆区空间呢,就还是希望被调用方法,这时就需要在类外作用域重载虚析构方法。但其实这么写父类本身也就无法实例化了,变成了抽象类。

13

相关文章

  • 18 类和对象--多态

    我们知道类的3大特性是封装,继承,多态。前2个将差不多了,多态其实也不难。 多态的基本概念 多态分为静态多态和动态...

  • 对像和类

    Java 对象和类 多态 继承 封装抽象 Java对象和类 类对象实例方法消息解析代码: 11 运行结果: 小狗的...

  • 2020-05-17--Java--day10【多态】

    多态概述 多态的格式和使用 代码当中体现多态性,其实就是一句话:父类引用指向子类对象。 格式: 父类名称 对象名 ...

  • Java的多态特性

    多态:对象的多种形态 1、引用多态 父类的引用可以指向本类的对象父类的引用可以指向子类的对象 2、方法多态 创建本...

  • 面对对象高级编程

    面向对象高级编程: 面向对象编程:封装、继承和多态 面向对象高级编程:多重继承、定制类和元类

  • 多态

    一、多态 1、引用多态父类的引用指向本类的对象父类的引用指向子类的对象 继承是实现多态的基础 2、方法多态创建本类...

  • 2.4 多态(面向对象)

    1、Java中的多态 对象的多种形态 引用多态父类的引用可以指向本类的对象父类的引用可以指向子类的对象 方法多态创...

  • 博学谷第十三天

    时间:2020年1月8日内容:多态、类方法、类属性 多态、类方法、类属性 多态 面向对象的三大特征: 封装将属性和...

  • songboyao- day01-1h

    面向对象特性 继承, 多态, 封装 类和对象 类是对象的模板, 对象是类的一个实例类是对一系列具有相同特征和行为的...

  • C++ 多态性 运算符重载

    注意:本文中代码均使用 Qt 开发编译环境 面向对象的多态性可以分为四类:重载多态、强制多态、包含多态和参数多态,...

网友评论

      本文标题:18 类和对象--多态

      本文链接:https://www.haomeiwen.com/subject/avxwvktx.html