总览
主要讲了 c++ 中封装的特性,以及一些示例
c++ 面向对象的三大特性,封装、继承、多态;和 Java 是一致的
c++认为万事万物皆对象,对象上有其属性和行为;对于类似属性和行为的对象,可以抽象为类
封装意义一:将属性和行为整合为一个整体
#include <iostream>
using namespace std;
// 设计一个圆类,可以计算周长
const double PI = 3.14159;
class Circle {
public:
int radius;
double calculateArea() {
return 2 * PI * radius;
}
};
int main() {
// 创建对象
Circle circle;
circle.radius = 10;
cout << circle.calculateArea() << endl;
return 0;
}
封装意义二:访问权限控制
类在设计时,可以把属性和行为放到不同的权限下,加以控制。
权限的类型有以下三种:
| 访问修饰符 | 同类中可访问 | 子类(派生类)可访问 | 同包/同文件(无) | 外部代码可访问 |
|---|---|---|---|---|
public | ✅ 是 | ✅ 是 | ✅ 是 | ✅ 是 |
protected | ✅ 是 | ✅ 是 | ✅ 是 | ❌ 否 |
private | ✅ 是 | ❌ 否(除非友元) | ❌ 否 | ❌ 否 |
对比 Java
Java 有默认的修饰符,同时 Java 的权限是基于包的,但是 c++ 中没有包的这个概念
| 访问修饰符 | 同类中可访问 | 同包中可访问 | 子类中可访问 | 全局可访问 |
|---|---|---|---|---|
public | ✅ | ✅ | ✅ | ✅ |
protected | ✅ | ✅ | ✅(跨包继承也可) | ❌(非子类不可) |
| 无修饰符(默认 / package-private) | ✅ | ✅ | ❌(即使继承也不行,除非同包) | ❌ |
private | ✅ | ❌ | ❌ | ❌ |
#include <iostream>
using namespace std;
class Person {
public:
int age;
protected:
string car;
private:
int password;
public:
void init() {
age = 20;
car = "BMW";
password = 123456;
}
};
int main() {
Person person;
cout << person.age << endl;
// protected、private权限类外访问不到
person.init(); // 这个函数由于在类内,可以访问任意属性
cout << person.car << endl;
cout << person.password << endl;
return 0;
}
和 struct 的区别
前面没讲 class 之前,我们会使用 struct 来将一组相关的变量组合起来,那么 class 和 struce 有什么区别呢?
唯一的区别在于默认的访问权限不同:
- class 的默认权限是private
- struct 的默认权限是 public
成员属性设置为私有
访问控制,类似于 Java 的 get、set方法
实现:即将所有属性都设置为 private,然后在类内手写属性的 get、set 方法,然后通过给get、set 方法设置不同的权限来控制对成员变量的读写权限
课后练习:设计立方体类
#include <iostream>
using namespace std;
class Cube {
private:
int line;
public:
int getArea() {
return 6 * line * line;
}
int getVolume() {
return line * line * line;
}
int getLine() {
return line;
}
void setLine(int line) {
this->line = line;
}
bool euqals(Cube c) {
return this->line == c.line;
}
};
bool isEqual(Cube c1, Cube c2) {
return c1.getLine() == c2.getLine();
}
int main() {
Cube c1;
Cube c2;
c1.setLine(3);
c2.setLine(3);
// 获取面积和体积
cout << c1.getArea() << endl;
cout << c1.getVolume() << endl;
// 全局函数判断
cout << isEqual(c1, c2) << endl;
// 成员函数判断
cout << c1.euqals(c2) << endl;
return 0;
}