OOP的主要原则之一是**封装原则,它说复杂的问题应该被分解成许多小问题,我们可以独立地同时解决。同时,我们作为用户并不关心它是如何发生的,数据(内部状态)仍然是孤立的。
例如,如果我们要解决的问题是如何根据用户查询的表达式"(5+3)*(2/(7+3)) "返回结果 "1.6",可能我们都无法写出一个能一次性解决这个问题的函数或方法。
**TIP:**在将数学表达式处理为字符串一文中,对这类例子有一个现成的解决方案,但要做好准备,这并不容易。
有了封装,你就可以 "作为用户 "使用对象,也就是说,调用它们的方法,而完全不用担心它们的内部工作方式。
假设我们正在处理计算一个雇员的工资,我们想使用另一个程序员的现有类来做这件事。我们只需要知道强制性的构造函数参数,就可以 "直接使用 "这个类。
$mzda = new MzdaZamestnance(25000, // 工资总额6, //在公司的年数10, // 工作年限true //是一个人吗?);echo $mzda->getHruba(); // 25000echo $mzda->getCista(); // 17800
对象的参数是虚构的,与工资的计算方式没有实际的对应关系。特别是,这个原则的说明是,我们只需要知道一般的公共接口,甚至不需要处理对象的内部状态,甚至不需要处理内部的实现,当然也不需要处理**它为什么以这种方式工作。我们只需调用getCista()
方法,即可得到净回报。
需要注意的是,封装本身并不是语言的一个特征或语法。事实上,一个类和应用程序是被封装的,只是程序员设计应用程序和思考代码的问题。
总是这样考虑班级设计。
对于处理内部逻辑的属性和方法,将可见性设置为`private'是有意义的。这样做的主要好处是,它们不会被外部调用,用户将被迫使用你设计的接口,从而保护数据和对象的内部状态。
例如,让我们有一个代表银行账户的对象,我们想在这里发布付款并处理当前的余额。
class BankAccount{private int $sum;public function __construct(int $startSum){$this->sum = $startSum >= 0 ? $startSum : 0;}public function getSum(): int{return $this->sum;}public function pay(int $price): void{$newSum = $this->sum - $price;if ($newSum < 0) {throw new \Exception('你没有那么多钱!');}$this->sum = $newSum;}public function addMoney(int $money): void{$this->sum += $money;}}
请注意,该类只包含一个private'属性
$sum',它包含当前的余额。
如果我们想获得当前的余额,有一个getSum()
的方法,但我们没有办法改变新的余额值。我们只能用pay()
方法删除钱,或用addMoney()
方法添加钱。
由于这一原则,我们总是可以肯定,没有人可以破坏这个物体。
如果用户试图支付比实际账户中更多的钱,pay()
方法将不允许,因为它在覆盖$sum
属性之前会进行检查计算,如果余额应该是负数(小于零),就会抛出一个错误异常,操作停止。
我们已经展示了封装的基本原理,这使我们能够更好地思考对象的抽象性,并带来一个全新的视角。
一旦你掌握了这个原则,你就会发现框架开始变得非常有意义,因为它们在内部封装了很多聪明的东西,你可以直接使用。
下一次我们将看一看dedicacy和visibility。
Jan Barášek Více o autorovi
Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.
Rád vám pomůžu:
Články píše Jan Barášek © 2009-2024 | Kontakt | Mapa webu
Status | Aktualizováno: ... | zh