一、 封装
作用:
封装(Encapsulation) 是面向对象编程(OOP)的核心特性之一,
把数据和操作数据的函数绑定在一起,并隐藏内部实现细节,防止外部代码直接访问对象的内部数据。
特点:
- 保护数据安全:防止外部代码直接修改数据。
- 提高代码可维护性:通过接口访问数据,修改实现时不会影响调用代码。
- 隐藏实现细节:外部代码无需关心类的内部逻辑,只需使用提供的接口。
- 增强可扩展性:可以在不修改接口的情况下改变内部实现。
二、 封装的基本实现
C++ 使用 private
、protected
、public
访问修饰符实现封装。
访问修饰符 | 作用 |
---|---|
private (默认) |
私有成员,只能在类的内部访问 |
protected |
保护成员,可在本类和子类访问 |
public |
公有成员,可被外部访问 |
示例 ------基本的封装:
cpp
#include <iostream>
using namespace std;
class Person {
private:
string name; // 私有成员,不能直接访问
int age;
protected:
string habit; // 本类和子类可以访问
public:
// 构造函数
Person(string n, int a, string s)
{
name = n;
age = a;
habit = s;
}
// 公有接口(getter 和 setter)
void setName(string n)
{
name = n;
}
string getName()
{
return name;
}
void setAge(int a)
{
if (a >= 0) age = a;
}
int getAge()
{
return age;
}
void setHabit(string s)
{
habit = s;
}
string getHabit()
{
return habit;
}
void display()
{
cout << "姓名: " << name << ", 年龄: " << age << ", 爱好: " << habit << endl;
}
};
int main() {
Person p("Alice", 25, "唱歌");
// p.name = "Bob"; // 错误:name 是 private,不能直接访问
// p.habit = "跳舞"; // 错误:name 是 protected,不能直接访问
p.setName("Bob"); // 正确 通过公有接口修改 name
p.setAge(30); // 正确 通过公有接口修改 age
p.setHabit("跳舞"); // 正确 通过公有接口修改 habit
cout << "姓名: " << p.getName() << endl;
p.display();
system("pause");
return 0;
}
注意:
name
和age
设为private
,habit
设为protected
,外部无法直接访问。- 数据成员一般设为
private
,使用公有接口 来间接访问和修改数据。 protected
主要用于继承,防止外部访问,但允许子类使用。
三、 getter
和 setter
方法
getter
(访问器):获取私有成员的值。setter
(修改器):设置私有成员的值,同时可以进行数据验证。
示例 ------使用 getter
和 setter
:
cpp
#include <iostream>
using namespace std;
class Car {
private:
int speed;
public:
// 构造函数
Car()
{
speed = 0;
}
// getter 方法
int getSpeed()
{
return speed;
}
// setter 方法(增加数据验证)
void setSpeed(int s)
{
if (s >= 0)
speed = s;
else
cout << "速度不能为负数!" << endl;
}
};
int main() {
Car car;
car.setSpeed(100);
cout << "当前速度: " << car.getSpeed() << " km/h" << endl;
car.setSpeed(-50); // 错误 触发数据验证
system("pause");
return 0;
}
使用 getter
和 setter
的作用:
- 防止直接修改数据,确保数据安全性。
- 提供数据验证机制,避免非法数据输入。
四、 特殊用法
(1)友元函数(Friend Function)
作用:
友元函数(friend
) 允许某些函数访问类的 private
成员,但该函数不属于该类的成员。
示例 ------友元函数访问私有数据:
cpp
#include <iostream>
using namespace std;
class Box {
// 友元函数声明
friend void printWidth(Box b);
private:
double width;
public:
Box(double w)
{
width = w;
}
};
// 友元函数定义
void printWidth(Box b)
{
cout << "Box 宽度: " << b.width << endl; // 访问 private 成员
}
int main() {
Box box(10.5);
printWidth(box); // 友元函数可以访问 private 数据
system("pause");
return 0;
}
友元函数的作用:
- 允许外部函数访问私有数据 ,但仍然保持封装。
- 不属于类的成员 ,不能用
this
访问对象。
(2)结构体 struct
的封装
在 C++ 中,struct
默认是 public
,但也可以使用 private
进行封装。
示例------使用 struct
进行封装:
cpp
struct Student {
private:
string name;
public:
void setName(string n)
{
name = n;
}
string getName()
{
return name;
}
};
注意:
- 简单的数据结构使用
struct
(如Point
)。 - 需要封装和继承时,使用
class
。