
C++面向对象核心:为什么 class 需要封装?
同学们,上节课我们学习了:
struct 和 class 的区别
我们知道:
class
默认:
private
也就是:
自己的数据,别人不能随便修改。
那么问题来了:
为什么 C++ 要设计 private?
为什么不让所有变量都 public,想改就改呢?
这就是今天要学习的核心:
封装(Encapsulation)
一、先看一个没有封装的世界
假设我们写一个学生类:
class Student
{
public:
string name;
int score;
};
使用:
Student s;
s.name="小明";
s.score=95;
看起来很方便。
但是问题来了:
如果有人写:
s.score=-100;
或者:
s.score=1000;
怎么办?
学生成绩应该:
0 ~ 100
但是现在:
-100
1000
都可以。
程序不会报错。
为什么?
因为:
score
是:
public
公开的。
任何人都可以改。
二、生活中的例子:银行卡
假设银行卡这样设计:
class BankCard
{
public:
double money;
};
然后:
BankCard card;
card.money=1000000;
任何人都可以:
card.money=999999999;
这显然不合理。
银行账户余额:
不能让别人直接修改。
所以真实世界设计:
银行卡:
外面只能:
-
存钱
-
取钱
-
查询余额
但是:
内部余额:
必须保护。
这就是:
封装
三、什么是封装?
一句话:
把重要的数据隐藏起来,只允许通过规定的方法访问。
英文:
Encapsulation
它包含两个动作:
1. 隐藏数据
使用:
private
2. 提供接口
使用:
public
例如:
class Student
{
private:
int score;
public:
void setScore(int x)
{
score=x;
}
int getScore()
{
return score;
}
};
现在:
score 藏起来了。
外面不能:
s.score=100;
错误。
必须:
s.setScore(100);
四、private到底有什么作用?
我们来看:
class Student
{
private:
int score;
};
private表示:
只有自己可以访问
比如:
类里面:
void test()
{
score=100;
}
可以。
但是外面:
Student s;
s.score=100;
不可以。
可以想象:
private 是:
房间里面的保险箱。
public 是:
房间门口的按钮。
别人不能直接打开保险箱。
只能按按钮。
五、getter 和 setter 是什么?
很多同学第一次看到:
get
set
不知道是什么意思。
其实非常简单:
getter
get:
获取
作用:
读取数据。
例如:
int getScore()
{
return score;
}
意思:
把成绩告诉外面。
setter
set:
设置
作用:
修改数据。
例如:
void setScore(int x)
{
score=x;
}
意思:
修改成绩。
所以:
| getter | get,读取 |
| setter | set,修改 |
六、为什么不直接访问,要绕一圈?
有同学可能问:
老师:
s.score
不是很方便吗?
为什么:
s.setScore(90);
这么麻烦?
答案:
因为:
我们可以增加规则!
例如:
成绩必须:
0~100
setter:
void setScore(int x)
{
if(x>=0 && x<=100)
{
score=x;
}
else
{
cout<<"成绩错误"<<endl;
}
}
现在:
s.setScore(150);
输出:
成绩错误
程序安全了。
七、封装最大的价值:控制修改
看两个程序:
没封装:
student.score=-999;
任何地方:
随便改。
后果:
程序容易出错。
有封装:
student.setScore(-999);
进入:
if
检查。
错误被挡住。
所以:
封装不是为了麻烦程序员。
而是:
为了让程序更安全、更容易维护。
八、封装和游戏角色的关系
比如游戏:
英雄:
class Hero
{
private:
int hp;
public:
void attack();
void heal();
};
血量:
hp
不能直接改。
否则:
玩家:
hp=999999
游戏就坏了。
所以:
只能:
攻击:
attack()
回血:
heal()
九、public、private、protected 三兄弟
C++ 有三个权限:
1. public(公开)
别人可以访问:
public:
int age;
像:
学校公告。
2. private(私有)
只有自己可以访问:
private:
int password;
像:
自己的密码。
3. protected(保护)
以后学习继承时使用。
现在可以简单理解:
给自己的孩子使用。
十、一个例子
设计一个银行账户:
#include<iostream>
using namespace std;
class Account
{
private:
double money;
public:
Account()
{
money=0;
}
void deposit(double x)
{
if(x>0)
{
money+=x;
}
}
double getMoney()
{
return money;
}
};
int main()
{
Account a;
a.deposit(100);
cout<<a.getMoney();
return 0;
}
输出:
100
注意:
外面不能:
a.money=1000000;
因为:
money 是私有的。
十一、封装和结构体有什么关系?
回忆:
struct:
struct Student
{
int score;
};
默认:
public
所以:
s.score=100;
可以。
class:
class Student
{
int score;
};
默认:
private
所以:
不能直接访问。
但是:
两者都可以封装。
例如:
struct:
struct Student
{
private:
int score;
};
也是合法的。
十二、信奥竞赛需要学封装吗?
学习 class 的意义在于:
培养:
-
大型程序设计思想
-
软件工程能力
-
AI时代编程能力
未来:
写:
-
游戏
-
App
-
人工智能项目
封装非常重要。
十三、本节课总结
记住下面这句话:
封装,就是把数据藏起来,把操作方法留下来。
关键词:
| private | 保护数据 |
| public | 提供服务 |
| getter | 读取数据 |
| setter | 修改数据 |
最终目标:
让对象自己管理自己,而不是让外部随便破坏。


