数据封装和数据抽象
数据封装
所有的 C++ 程序都有以下两个基本要素:
- 程序语句(代码):这是程序中执行动作的部分,它们被称为函数。
- 程序数据:数据是程序的信息,会受到程序函数的影响。
数据封装(Data Encapsulation)是面向对象编程(OOP)的一个基本概念,它通过将数据和操作数据的函数封装在一个类中来实现。这种封装确保了数据的私有性和完整性,防止了外部代码对其直接访问和修改。
实例1
2
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
33
34
35
using namespace std;
class Adder{
public:
// 构造函数
Adder(int i = 0)
{
total = i;
}
// 对外的接口
void addNum(int number)
{
total += number;
}
// 对外的接口
int getTotal()
{
return total;
};
private:
// 对外隐藏的数据
int total;
};
int main( )
{
Adder a;
a.addNum(10);
a.addNum(20);
a.addNum(30);
cout << "Total " << a.getTotal() <<endl;
return 0;
}
公有成员 addNum
和 getTotal
是对外的接口,用户需要知道它们以便使用类。私有成员 total
是对外隐藏的,用户不需要了解它,但它又是类能正常工作所必需的。数据封装通过类和访问修饰符(public
, private
, protected
)来实现.
通常情况下,我们都会设置类成员状态为私有(private
),除非我们真的需要将其暴露,这样才能保证良好的封装性。这通常应用于数据成员,但它同样适用于所有成员,包括虚函数。
数据抽象
数据抽象是指只向外界暴露对象的必要接口,隐藏其内部实现细节,强调“做什么”而非“怎么做”。抽象的目标是简化复杂系统,提供一种更高级别的理解方式。
数据抽象是一种依赖于接口和实现分离的编程(设计)技术。
关键点:
- 关注接口而非实现:用户只需要知道如何使用对象,而不需要了解其内部运作。
- 减少复杂性:将实现细节隐藏起来,减少用户处理信息的负担。
- 依赖抽象层:通过定义抽象类或接口实现更灵活的代码。
1
2
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
33
34
35
36
using namespace std;
// 抽象类:定义一个接口
class Shape {
public:
virtual void draw() const = 0; // 纯虚函数
virtual ~Shape() {}
};
class Circle : public Shape {
public:
void draw() const override {
cout << "Drawing a Circle" << endl;
}
};
class Rectangle : public Shape {
public:
void draw() const override {
cout << "Drawing a Rectangle" << endl;
}
};
int main() {
Shape* shape1 = new Circle();
Shape* shape2 = new Rectangle();
shape1->draw(); // 只需要调用接口,不关心内部实现
shape2->draw();
delete shape1;
delete shape2;
return 0;
}
区别
数据封装和数据抽象概念的区别
特性 | 数据封装 | 数据抽象 |
---|---|---|
核心概念 | 绑定数据和操作,并隐藏数据的实现细节。 | 仅暴露接口,隐藏实现的复杂性。 |
目标 | 保护数据,避免被外部非法访问或修改。 | 简化接口,强调“做什么”而非“怎么做”。 |
实现手段 | 通过访问修饰符(private, protected, public)。 | 通过抽象类、接口和多态。 |
使用范围 | 主要在类的成员变量和成员函数中实现。 | 主要在类和对象的设计层次。 |