私有和受保护属性
本课属于 Coddy PHP 学习旅程的“面向对象编程”单元。第 18 课,共 91 课。
到目前为止,我们一直使用可以从任何地方访问的 public 属性。但有时你需要限制访问,以保护数据。PHP 还提供了两种可见性修饰符:private 和 protected。
private 属性只能在定义它的类内部访问:
<?php
class BankAccount {
private $balance = 0;
public function deposit($amount) {
$this->balance += $amount;
}
public function getBalance() {
return $this->balance;
}
}
$account = new BankAccount();
$account->deposit(100);
echo $account->getBalance();
输出:
100如果尝试在类外部直接访问 $account->balance,就会导致错误。这样可以保护余额,避免它未通过 deposit 方法就被更改。
protected 属性的作用类似,但扩展父类的子类也可以访问它:
<?php
class User {
protected $email;
public function __construct($email) {
$this->email = $email;
}
}
class Admin extends User {
public function showEmail() {
return $this->email;
}
}
$admin = new Admin("admin@example.com");
echo $admin->showEmail();
输出:
admin@example.com要点:只有定义该属性的类应该访问它时,使用 private。子类也需要访问时,使用 protected。这两者都能阻止外部直接访问,保护对象的内部状态。
挑战
简单我们来构建一个安全的员工管理系统,演示如何使用 private 和 protected 属性保护敏感数据。
你将创建三个协同工作的文件,通过适当的访问控制来管理员工信息:
Employee.php:定义一个作为所有员工基类的Employee类。它应有一个protected $name属性(这样子类就能访问它),以及一个private $salary属性(只有这个类才能直接修改薪水)。构造函数接收姓名和薪水,并设置这两个属性。添加一个返回姓名的 publicgetName()方法、一个返回薪水的 publicgetSalary()方法,以及一个按给定金额增加薪水的 publicgiveRaise($amount)方法。Manager.php:定义一个继承Employee的Manager类。在文件顶部引入 Employee 文件。添加一个 private$department属性。构造函数应接收姓名、薪水和部门:使用parent::__construct($name, $salary)调用父类构造函数,然后设置部门。创建一个getDetails()方法,通过直接访问 protected$name属性,返回"[name] manages [department]"。另外,添加一个返回部门的getDepartment()方法。main.php:引入这两个类文件。创建一个Manager,姓名为"Sarah",薪水为75000,部门为"Engineering"。使用getDetails()输出经理的详细信息。然后给经理加薪5000,并使用getSalary()输出加薪后的薪水。每条输出都应单独占一行。
注意,Manager 类可以直接访问 protected $name 属性,但必须使用 getSalary() 方法来访问 private 薪水。这展示了 protected 和 private 可见性的关键区别:protected 允许子类访问,而 private 会将数据真正隐藏起来。
亲手试试
<?php
require_once 'Employee.php';
require_once 'Manager.php';
// TODO: 创建一个 Manager,姓名为 "Sarah",薪资为 75000,部门为 "Engineering"
// TODO: 使用 getDetails() 输出经理的详细信息
// TODO: 给经理加薪 5000
// TODO: 使用 getSalary() 输出新薪资
?>这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: PHP 在线编译器