获取方法和设置方法
本课属于 Coddy PHP 学习旅程的“面向对象编程”单元。第 40 课,共 91 课。
现在你已经了解了访问修饰符,那么如何在类外部安全地访问私有属性呢?答案是获取器和设置器,它们是能够受控地访问私有数据的公有方法。
getter 用于获取属性的值,而 setter 用于修改属性。使用这种模式,你可以在访问或更改数据时添加验证或逻辑:
<?php
class User {
private string $email;
private int $age;
public function getEmail(): string {
return $this->email;
}
public function setEmail(string $email): void {
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
$this->email = $email;
}
}
public function getAge(): int {
return $this->age;
}
public function setAge(int $age): void {
if ($age >= 0 && $age <= 150) {
$this->age = $age;
}
}
}
$user = new User();
$user->setEmail("john@example.com");
$user->setAge(25);
echo $user->getEmail() . "\n";
echo $user->getAge();
输出:
john@example.com
25setter 会在存储值之前验证电子邮件格式,并确保年龄合理。如果没有 setter,任何人都可以直接赋予无效数据。你也可以只提供 getter 来创建只读属性,或者只提供 setter 来创建只写属性。
要点:获取器和设置器可以让你控制如何访问和修改私有数据,还可以进行验证、格式化或执行任何自定义逻辑。
挑战
简单让我们构建一个产品库存系统,使用获取器和设置器来保护并验证产品数据。你将创建一个 Product 类,确保价格始终为正数,库存数量永远不会是负数:这展示了设置器如何强制执行业务规则。
你将把代码分成两个文件:
Product.php:创建一个Product类,包含三个私有属性:$name(字符串)、$price(浮点数)和$stock(整数)。为每个属性实现获取器和设置器,并遵循以下验证规则:setName()只能接受非空字符串。如果字符串去除首尾空白后为空,则不要更新属性。setPrice()只能接受大于 0 的值:拒绝零或负数价格。setStock()只能接受大于或等于 0 的值:拒绝负数库存。
getInfo(),使其返回"[name]: $[price] ([stock] in stock)",并将价格格式化为 2 位小数。main.php:引入 Product 文件。你会收到 4 个输入:产品名称、价格、库存数量,以及用于更新价格的新价格。创建一个Product实例,并使用设置器设置初始名称、价格(转换为浮点数)和库存(转换为整数)。打印getInfo()的结果。然后尝试使用新价格值(转换为浮点数)更新价格,并再次打印getInfo()。最后,尝试将库存设置为-5(无效值),再打印一次getInfo(),以确认库存没有改变。
你的设置器就像把关者。它们会先验证传入的数据,再允许修改私有属性。传入无效数据时(例如负数库存),设置器只会忽略它,并保留现有的有效值。这就是封装的作用:无论外部代码尝试做什么,你的对象都能保持完整性。
亲手试试
<?php
require_once 'Product.php';
// 读取输入
$name = trim(fgets(STDIN));
$price = trim(fgets(STDIN));
$stock = trim(fgets(STDIN));
$newPrice = trim(fgets(STDIN));
// TODO: 创建一个新的 Product 实例
// TODO: 使用 setter 方法设置初始名称、价格(浮点数)和库存(整数)
// TODO: 打印 getInfo() 的结果
// TODO: 用 newPrice(浮点数)更新价格,并再次打印 getInfo() 的结果
// TODO: 尝试将库存设置为 -5(无效值),并打印 getInfo() 的结果,确认库存未改变
?>这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: PHP 在线编译器