概述
C++ 是面向对象的语言,具备 OOP 的基本特性。
封装
- 概念
- 将数据和操作数据的函数绑定在一起
- 作用
- 避免受到外界的干扰和误用,确保了安全
- 与封装相关的概念
- 数据抽象
- 仅向用户暴露接口而把具体的实现细节隐藏起来的一种机制,是一种依赖于接口和实现相分离的编程技术
- 好处
- 类的内部收到保护,不会因无意的用户级错误导致对象状态受损
- 可以在只改变类的实现细节,而不改变用户级代码的情况下,应对变化的需求
- 注意
- 要尽量地对外隐藏每个类的实现细节
- 友元类回暴露类的实现细节,降低封装性
- 策略
- 抽象将代码分离为接口和实现,在设计组件时,必须保持接口独立于实现。保证底层实现改变时,接口保持不变
- 接口
- 基于抽象类实现。描述类的行为和功能,不关注类的特定实现
- 抽象类
- 类中至少有一个函数被定义为纯虚函数
- 作用
- 为其他类提供一个可以继承的适当的基类
- 作为作为接口
- 注意
- 抽象类不能被实例化,
- 具体类(与抽象类相对应)可以被实例化
- 策略
- 面向对象的系统通常使用一个抽象类为外部应用程序提供一个适当的、通用的、标准化的接口。派生类通过集成抽象基类,来集成类似的操作
- 外部应用程序通过实现抽象基类中的纯虚函数,来提供功能
- 数据抽象
继承
-
概念
- 继承是 OOP 中一个重要的概念,代表了一种 is a 的关系
-
作用
- 提高了代码重用率和执行效率
-
单继承与多继承
-
单继承
class derived-class: access-specifier base-class /** base-class 为基类 derived-class 为派生类 access-specifier 访问控制符, */
-
多继承
class derived-class: access-specifier baseA, access-specifier baseB....
-
-
继承中的访问控制
访问修饰符 public protected private 同一个类 yes yes yes 派生类 yes yes no 外部类 yes no no -
继承的类型(通过access-specifier指定)
- 公有继承
- 基类中的公有成员和保护成员分别成为派生类中对应的公有成员和保护成员;基类中私有成员不能被派生类直接访问,可以通过调用基类的公有成员和保护成员来间接访问
- 保护继承
- 基类中的公有成员和保护成员成为派生类中的保护成员
- 私有继承
- 基类中的公有成员和保护成员成为派生类中的私有成员
- 公有继承
-
注意
- 派生类继承了绝大部分的基类方法,下列方法除外
- 构造函数、拷贝构造函数和析构函数
- 重载运算符
- 友元函数
- 派生类继承了绝大部分的基类方法,下列方法除外
多态
- 概念
- 调用成员函数期间,根据调用函数的对象的类型动态的决定最终调用的函数(虚函数)实现
- 基于继承和虚函数实现,是一种动态绑定技术
- 使用场景
- 成员函数调用时,子类对象调用相应的子类成员函数
- 向成员函数传递参数时,父类类型的参数可以传递子类对象
- 与多态相关的概念
- 静态连接(早绑定)
- 在程序执行之前,编译器设置对象内容决定调用响应的函数
- 动态连接(后期绑定)
- 在程序执行期间,根据所调用的对象类型来选择调用的函数
- 虚函数会告诉编译器不要在程序执行之前根据对象内容决定决定最终调用的函数(静态连接),等到程序执行时根据所调用的对象类型来选择调用的函数(动态连接)
- 静态连接(早绑定)
示例
-
辅助的枚举类型
// 脊椎动物动物的分类 enum AnimalType { AnimalTypeMammalia, // 哺乳类 AnimalTypeAves, AnimalTypePisces, AnimalTypeAmphibia, AnimalTypeReptilia, AnimalTypeCyclostomata };
-
基类
// 基类 /** Animal */ class Animal { // 属性 public: string name; // 姓名,每个动物都具有名字 protected: enum AnimalType type; // 动物类别,只有确定的动物才有类别 private: double lifeTime; // 寿命,不允许随便设置 // 方法 public: void setName(char n[]) { name = n; } string getName() { return name; } // 声明函数,在派生类中实现,多态的一种形式 void setType(); };
-
接口
// 接口 /** AnimalActivity是一个抽象类,作为一个接口,描述了Animal相关的行为 */ class AnimalActivity { public: // 纯虚函数,描述Animal的行为 virtual void run() = 0; };
-
派生类
// 派生类 /** Dog类 */ class Dog : public Animal, public AnimalActivity { // 方法 public: // 实现基类Animal中的函数 void setType() { cout << "设置了Dog的类别" << endl; type = AnimalTypeMammalia; } // 实现接口AnimalActivity中的纯虚函数 void run() { cout << "Dog: " << name; cout << " 在奔跑着追老鼠" << endl; } }; /** Cat类 */ class Cat : public Animal, public AnimalActivity { // 方法 public: // 实现基类Animal中的函数 void setType() { cout << "设置了Cat的类别" << endl; type = AnimalTypeMammalia; } // 实现接口AnimalActivity中的纯虚函数 void run() { cout << "Cat: " << name; cout << " 在奔跑着追小偷" << endl; } };
-
使用方法
int main(int argc, const char * argv[]) { // 创建对象 Animal animal; Dog MAX; Cat TOM; // Dog的相应操作 MAX.name = "MAX"; MAX.setType(); MAX.run(); cout << endl; // Cat的相应操作 TOM.name = "Tom"; TOM.setType(); TOM.run(); return 0; }