#### 24. 多态
**多态**按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。
C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。
下面的实例中,基类 Shape 被派生为两个类,如下所示:
~~~
//1. 定义了一个 Person 基类,跟 Java class 差不多
class Person {
public: //公共的属性
Person();
~Person();
Person(char *name, char *gen, int age);
char *name;
char *gen;
int age;
void setName(char *name);
char *getName();
void setGen(char *gen);
char *getGen();
void setAge(int age);
int getAge();
/**
* 虚函数 是在基类中使用关键字 virtual 声明的函数。
* 在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。
* @return
*/
//virtual 转移给子类实现
virtual int test() {
return 10;
};
};
//2. 定义 DevYK 派生类
class DevYK : public Person {
public:
DevYK(char *name, int age) : Person(name, "nan", age) {};
int length;
DevYK();
~DevYK();
char *getPersonName();
void setLength(int len);
int getLength();
DevYK operator+(const DevYK &b);
char *getName();
int test() {
return -10;
};
};
//3. .cpp 文件
#include "ClssSample.h"
#include <iostream>
using namespace std;
Person::Person(char *name, char *gen, int age) {
this->name = name;
this->age = age;
this->gen = gen;
}
Person::~Person() {
cout << "Person 销毁" << endl;
}
Person::Person() {
cout << "执行 Person 空参构造函数" << endl;
}
void Person::setAge(int age) {
this->age = age;
}
void Person::setName(char *name) {
this->name = name;
}
void Person::setGen(char *gen) {
this->gen = gen;
}
char *Person::getName() {
return this->name;
}
char *Person::getGen() {
return this->gen;
}
int Person::getAge() {
return this->age;
}
DevYK::DevYK() {
cout << "执行 DevYK 空参构造函数" << endl;
}
DevYK::~DevYK() {
cout << "DevYK 销毁" << endl;
}
char *DevYK::getName() {
cout << "DevYK getName" << endl;
return this->name;
}
char *DevYK::getPersonName() {
return this->name;
}
void DevYK::setLength(int len) {
this->length = len;
}
int DevYK::getLength() {
return this->length;
}
// 重载 + 运算符,用于把两个 Box 对象相加
class DevYK DevYK::operator+(const class DevYK &b) {
DevYK devYk;
devYk.length = this->length + b.length;
return devYk;
}
//3. 测试
void test22() {
//父类
Person *person;
//定义子类
DevYK devYk("DevYK", 27);
if (person) {
cout << "Person\t" << person->getName() << "\t" << person->getGen() << "\t" << person->getAge() << endl;
}
cout << "DevYK->\t" << devYk.getName() << "\t" << devYk.getGen() << "\t" << devYk.getAge() << endl;
//把 devyk 的内存地址赋值给 person
person = &devYk;
if (person) {
cout << "Person\t" << person->getName() << "\t" << person->getGen() << "\t" << person->getAge() << endl;
}
cout << "DevYK 内存地址->\t" << &devYk << " Person 内存地址\t" << person << endl;
//获取子类数据
int test = person->test();
cout << "test->\t" << test << endl;
}
复制代码
~~~
> **输出:**
>
> DevYK-> DevYK getName DevYK nan 27 Person DevYK nan 27 DevYK 内存地址-> 0x7ffee1d26628 Person 内存地址 0x7ffee1d26628 test-> -10 DevYK 销毁 Person 销毁
**虚函数:**
**虚函数** 是在基类中使用关键字 **virtual** 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。
我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为**动态链接**,或**后期绑定**。
**纯虚函数:**
您可能想要在基类中定义虚函数,以便在派生类中重新定义该函数更好地适用于对象,但是您在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。
- 前言
- JNI基础知识
- C语言知识点总结
- ①基本语法
- ②数据类型
- 枚举类型
- 自定义类型(类型定义)
- ③格式化输入输出
- printf函数
- scanf函数
- 编程规范
- ④变量和常量
- 局部变量和外部变量
- ⑤类型转换
- ⑥运算符
- ⑦结构语句
- 1、分支结构(选择语句)
- 2、循环结构
- 退出循环
- break语句
- continue语句
- goto语句
- ⑧函数
- 函数的定义和调用
- 参数
- 函数的返回值
- 递归函数
- 零起点学通C语言摘要
- 内部函数和外部函数
- 变量存储类别
- ⑨数组
- 指针
- 结构体
- 联合体(共用体)
- 预处理器
- 预处理器的工作原理
- 预处理指令
- 宏定义
- 简单的宏
- 带参数的宏
- 预定义宏
- 文件包含
- 条件编译
- 内存中的数据
- C语言读文件和写文件
- JNI知识点总结
- 前情回顾
- JNI规范
- jni开发
- jni开发中常见的错误
- JNI实战演练
- C++(CPP)在Android开发中的应用
- 掘金网友总结的音视频开发知识
- 音视频学习一、C 语言入门
- 1.程序结构
- 2. 基本语法
- 3. 数据类型
- 4. 变量
- 5. 常量
- 6. 存储类型关键字
- 7. 运算符
- 8. 判断
- 9. 循环
- 10. 函数
- 11. 作用域规则
- 12. 数组
- 13. 枚举
- 14. 指针
- 15. 函数指针与回调函数
- 16. 字符串
- 17. 结构体
- 18. 共用体
- 19. typedef
- 20. 输入 & 输出
- 21.文件读写
- 22. 预处理器
- 23.头文件
- 24. 强制类型转换
- 25. 错误处理
- 26. 递归
- 27. 可变参数
- 28. 内存管理
- 29. 命令行参数
- 总结
- 音视频学习二 、C++ 语言入门
- 1. 基本语法
- 2. C++ 关键字
- 3. 数据类型
- 4. 变量类型
- 5. 变量作用域
- 6. 常量
- 7. 修饰符类型
- 8. 存储类
- 9. 运算符
- 10. 循环
- 11. 判断
- 12. 函数
- 13. 数学运算
- 14. 数组
- 15. 字符串
- 16. 指针
- 17. 引用
- 18. 日期 & 时间
- 19. 输入输出
- 20. 数据结构
- 21. 类 & 对象
- 22. 继承
- 23. 重载运算符和重载函数
- 24. 多态
- 25. 数据封装
- 26. 接口(抽象类)
- 27. 文件和流
- 28. 异常处理
- 29. 动态内存
- 30. 命名空间
- 31. 预处理器
- 32. 多线程
- 总结
- 音视频学习 (三) JNI 从入门到掌握
- 音视频学习 (四) 交叉编译动态库、静态库的入门学习
- 音视频学习 (五) Shell 脚本入门
- 音视频学习 (六) 一键编译 32/64 位 FFmpeg 4.2.2
- 音视频学习 (七) 掌握音频基础知识并使用 AudioTrack、OpenSL ES 渲染 PCM 数据
- 音视频学习 (八) 掌握视频基础知识并使用 OpenGL ES 2.0 渲染 YUV 数据
- 音视频学习 (九) 从 0 ~ 1 开发一款 Android 端播放器(支持多协议网络拉流/本地文件)
- 音视频学习 (十) 基于 Nginx 搭建(rtmp、http)直播服务器
- 音视频学习 (十一) Android 端实现 rtmp 推流
- 音视频学习 (十二) 基于 FFmpeg + OpenSLES 实现音频万能播放器
- 音视频学习 (十三) Android 中通过 FFmpeg 命令对音视频编辑处理(已开源)