Công khai, được bảo vệ, riêng tư
Thuộc phần Lập trình hướng đối tượng trong hành trình PHP của Coddy. Bài học 38 trên 91.
Chào mừng bạn đến với chương về tính đóng gói! Tính đóng gói giúp kiểm soát quyền truy cập vào dữ liệu bên trong lớp của bạn. PHP cung cấp ba phạm vi truy cập để xác định nơi có thể truy cập thuộc tính và phương thức: public, protected và private.
Sau đây là cách hoạt động của từng từ sửa đổi:
<?php
class BankAccount {
public $accountHolder; // Có thể truy cập từ mọi nơi
protected $accountNumber; // Có thể truy cập trong lớp này và các lớp con
private $balance; // Chỉ có thể truy cập trong lớp này
public function __construct($holder, $number, $balance) {
$this->accountHolder = $holder;
$this->accountNumber = $number;
$this->balance = $balance;
}
public function getBalance() {
return $this->balance;
}
}
$account = new BankAccount("John", "12345", 1000);
echo $account->accountHolder . "\n"; // Chạy được vì có quyền truy cập công khai
echo $account->getBalance(); // Chạy được vì đây là phương thức công khai
Đầu ra:
John
1000Truy cập trực tiếp vào $account->balance sẽ gây ra lỗi vì thuộc tính này là riêng tư. Điều tương tự cũng áp dụng với $account->accountNumber khi truy cập từ bên ngoài hệ thống phân cấp lớp. Cơ chế bảo vệ này đảm bảo rằng chỉ có thể sửa đổi dữ liệu nhạy cảm thông qua các phương thức được kiểm soát.
| Bộ điều chỉnh | Cùng lớp | Lớp con | Bên ngoài |
|---|---|---|---|
public | Có | Có | Có |
protected | Có | Có | Không |
private | Có | Không | Không |
Điểm chính: Dùng private cho dữ liệu nội bộ không nên được truy cập trực tiếp, protected cho dữ liệu mà các lớp con cần dùng và chỉ dùng public để cho phép truy cập từ bên ngoài một cách an toàn.
Thử thách
DễHãy xây dựng một hệ thống quản lý nhân viên an toàn để minh họa cách các bộ sửa đổi quyền truy cập bảo vệ dữ liệu nhạy cảm. Bạn sẽ tạo một hệ thống phân cấp lớp, trong đó các cấp thông tin khác nhau có thể được truy cập tùy theo nơi code đang chạy: bên trong lớp, trong lớp con hoặc từ bên ngoài.
Bạn sẽ sắp xếp code trong ba tệp:
Employee.php: Tạo lớpEmployeeđể quản lý dữ liệu nhân viên với các cấp độ hiển thị phù hợp. Lớp này cần có:- Thuộc tính
public$namelưu tên nhân viên, mọi người đều có thể xem an toàn - Thuộc tính
protected$employeeIdlưu mã nhân viên nội bộ, cần thiết cho các lớp con - Thuộc tính
private$salarylưu thông tin lương nhạy cảm, chỉ lớp này mới có thể truy cập trực tiếp
getSalary()để trả về mức lương riêng tư. Đây là cách có kiểm soát để truy cập dữ liệu được bảo vệ. Đồng thời, thêm phương thức công khaigetPublicInfo()để trả về"[name] works here".- Thuộc tính
Manager.php: Tạo lớpManagerkế thừaEmployee. Bao gồm tệp Employee. Hàm khởi tạo cần nhận tên, employeeId, salary và tên phòng ban. Gọi hàm khởi tạo của lớp cha với ba giá trị đầu tiên, sau đó lưu phòng ban vào một thuộc tính riêng tư. Thêm phương thức công khaigetTeamInfo()để trả về"Manager [name] (ID: [employeeId]) leads [department]". Lưu ý rằng lớp con có thể truy cập$employeeIdđược bảo vệ, nhưng cần dùnggetSalary()để truy cập mức lương riêng tư.main.php: Bao gồm tệp Manager. Bạn sẽ nhận bốn đầu vào: tên, mã nhân viên, mức lương dưới dạng chuỗi để chuyển thành số nguyên và tên phòng ban. Tạo một đối tượngManagerbằng các giá trị này. In ra ba dòng:- Tên của người quản lý, được truy cập trực tiếp qua thuộc tính công khai
- Kết quả gọi
getTeamInfo() - Kết quả gọi
getSalary()
Thử thách này minh họa cách đóng gói hoạt động: mọi người có thể tự do truy cập tên, mã nhân viên được chia sẻ với các lớp con thông qua khả năng hiển thị protected, còn mức lương vẫn được giữ kín trong lớp cha và chỉ có thể truy cập thông qua một phương thức công khai có kiểm soát.
Tự làm thử
<?php
require_once 'Manager.php';
// Đọc các giá trị đầu vào
$name = trim(fgets(STDIN));
$employeeId = trim(fgets(STDIN));
$salary = intval(trim(fgets(STDIN)));
$department = trim(fgets(STDIN));
// TODO: Tạo một instance của Manager bằng các giá trị đầu vào
// TODO: In ra tên của manager (truy cập trực tiếp qua thuộc tính public)
// TODO: In ra kết quả khi gọi getTeamInfo()
// TODO: In ra kết quả khi gọi getSalary()
?>Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Nền tảng về OOP
Tệp bên ngoàiGiới thiệu về OOPLớp và đối tượngTừ khóa $thisPhương thứcThuộc tínhHàm khởi tạo (__construct)Hàm hủy (__destruct)Ôn tập: máy tính đơn giản4Kế thừa
Kế thừa cơ bảnTừ khóa parent::Ghi đè phương thứcTừ khóa finalLớp trừu tượngÔn tập: hệ thống phân cấp nhân viên7Đóng gói
Công khai, được bảo vệ, riêng tưTìm hiểu sâu về bộ điều chỉnh quyền truy cậpGetter và setterẨn thông tinRút gọn hàm khởi tạo (8.0)Ôn tập: hệ thống hồ sơ học sinh2Không gian tên và tự động nạp
Giới thiệu về không gian tênTừ khóa useChuẩn tự động nạp PSR-4Trình tự động nạp của ComposerÔn tập: dự án có tổ chức5Giao diện và hợp đồng
Giới thiệu về giao diệnTriển khai giao diệnTriển khai nhiều giao diệnGiao diện và lớp trừu tượngGợi ý kiểu với giao diệnÔn tập: Máy tính hình học8Phương thức ma thuật
Giới thiệu về phương thức ma thuật__toString và __debugInfo__get, __set, __isset, __unset__call và __callStatic__clone và sao chép đối tượng__serialize và __unserializeÔn tập: Bộ sưu tập tùy chỉnh3Thuộc tính của lớp
Thuộc tính instance và staticHằng số trong lớpPhương thức và thuộc tính staticThuộc tính private và protectedThuộc tính chỉ đọc (PHP 8.1)Ôn tập: Trình quản lý tài khoản ngân hàng6Đa hình
Xem lại việc ghi đè phương thứcĐa hình qua giao diệnGợi ý kiểu và kiểu hợpLiên kết tĩnh muộnÔn tập: bộ xử lý thanh toánTự luyện tập: Trình biên dịch PHP online