【新手向】从一行报错搞懂什么是面向对象封装
豆包生成
好的,我来写一篇适合编程新手的博客园随笔。
【新手向】从一行报错搞懂什么是面向对象封装
前言
今天改一个PHP接单接口,第29行报了个错:
$json["message"] = $DB_API->error; // 报错:Cannot access private property
我当时就懵了:不就是拿个错误信息吗,为啥不让我直接拿?还要调用什么 errorMsg() 方法?
后来查了资料才明白,这就是面向对象里的「封装」。今天就用大白话聊聊这个概念,写给和我一样的新手。
一、先讲个故事:自动售货机
想象一下你去买可乐:
✅ 正常用法:投币 → 按按钮 → 可乐出来
❌ 不正常用法:直接拆机器 → 伸手进去拿可乐
为什么售货机要做成箱子,只留几个按钮给你按?
- 安全:你伸手进去可能触电,也可能把里面的零件碰坏
- 公平:不能想拿几瓶就拿几瓶,得按规则来
- 省心:机器内部怎么工作你不用管,会按按钮就行
面向对象的封装,和自动售货机是一个道理。
二、回到代码:私有属性 vs 公共方法
我们看这个数据库类的代码:
class DB_API {
// 私有属性:就像售货机内部的钱箱,外面碰不到
private $error;
// 公共方法:就像售货机的按钮,按一下才给你结果
public function errorMsg() {
return $this->error;
}
}
为什么不直接写成 public?
新手可能会说:直接改成 public $error; 不就完了,费这劲干嘛?
还真不是多此一举,有三个实实在在的好处:
好处1:防止数据被乱改
如果 $error 是公开的,别人可以随便写:
// 如果是 public,就会出这种事
$DB_API->error = "我随便编的错误"; // ❌ 真实错误信息被覆盖了
改成私有后,只有类内部的代码才能修改 $error,外部只能读,保证了数据的真实性。
好处2:内部改了,外部不用变
假设以后作者想升级,把错误信息改成带错误码的格式:
// 内部实现改了
private $error = ['code' => 500, 'msg' => '数据库连接失败'];
// 但对外的方法不变
public function errorMsg() {
return $this->error['msg']; // 内部处理一下再返回
}
你调用的代码完全不用改,还是 $DB_API->errorMsg()。
这就叫「高内聚,低耦合」——内部怎么折腾是内部的事,对外的接口保持稳定。
好处3:返回前可以做点额外操作
比如想在返回错误信息的同时,自动记个日志:
public function errorMsg() {
// 偷偷记个日志,外部完全不知道
file_put_contents('db_error.log', $this->error . "\n", FILE_APPEND);
return $this->error;
}
如果直接暴露属性,就没法在「读取」这个动作上附加功能了。
三、新手常见疑问
Q:我写小脚本也要这么搞吗?
A:不用。 封装是为了应对复杂项目。如果你写个几十行的小脚本,自己用,直接用变量完全没问题。
什么时候需要封装?
- 写的代码要给别人用
- 项目比较大,以后要维护
- 多人协作开发
Q:我之前写代码都是直接用变量,是不是错了?
A:不是错,是不同的编程风格。
你之前写的可能是「面向过程」的代码,就像做蛋炒饭:一步一步按顺序来。
而面向对象更像搭乐高:把功能封装成一个个积木,需要的时候拼起来。
没有谁好谁坏,看场景。
Q:这个数据库类是谁写的?
A:是一个叫 TANKING 的博主写的通用类。 这种封装写法是行业标准,不是他发明的。Java、C#、Python 都是这么玩的。
四、一句话总结
封装就是:把数据藏起来,只留几个方法给外面用。
就像你用手机:
- 内部芯片、电池、电路板怎么工作你不用管(私有)
- 你只需要会按电源键、点屏幕就行(公共方法)
后记
我也是刚接触面向对象不久,一开始也觉得「这不是脱裤子放屁吗」。
后来项目大了才发现:
- 不封装的代码,写的时候爽,改的时候哭
- 封装好的代码,写的时候麻烦,用的时候真香
编程这条路,很多概念都是「初听觉得多余,踩过坑才懂为什么」。
慢慢来,踩坑多了就懂了。
如果这篇文章对你有帮助,欢迎推荐+关注~ 我是正在学PHP的新手,一起加油!
需要我调整风格、增减内容,或者改成其他平台(比如知乎、掘金)的风格吗?
浙公网安备 33010602011771号