Từ khóa final
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 24 trên 91.
Kế thừa và ghi đè phương thức mang lại sự linh hoạt, nhưng đôi khi bạn cần ngăn một số lớp hoặc phương thức bị thay đổi. Từ khóa final khóa chặt code, đảm bảo các cách triển khai cụ thể không thể bị lớp con thay đổi.
Khi bạn đánh dấu một phương thức là final, không lớp con nào có thể ghi đè phương thức đó:
<?php
class BankAccount {
protected $balance;
public function __construct($balance) {
$this->balance = $balance;
}
final public function getAccountId() {
return "ACC-" . spl_object_id($this);
}
}
class SavingsAccount extends BankAccount {
public function addInterest() {
return $this->balance * 0.05;
}
}
$account = new SavingsAccount(1000);
echo $account->getAccountId();
Đầu ra:
ACC-1Không thể ghi đè phương thức getAccountId() trong SavingsAccount hoặc bất kỳ lớp con nào khác. Điều này bảo vệ chức năng quan trọng cần giữ nhất quán giữa tất cả các loại tài khoản.
Bạn cũng có thể đánh dấu toàn bộ một lớp là final để ngăn mọi kế thừa:
<?php
final class SecurityManager {
public function authenticate($user) {
return "Authenticating $user";
}
}
$security = new SecurityManager();
echo $security->authenticate("admin");
Đầu ra:
Authenticating adminKhông lớp nào có thể kế thừa SecurityManager. Điều này hữu ích với các lớp nhạy cảm về bảo mật hoặc khi thiết kế lớp đã hoàn chỉnh và không nên sửa đổi.
Điểm chính: Dùng final cho các phương thức để ngăn ghi đè nhưng vẫn cho phép kế thừa, hoặc dùng cho các lớp để ngăn kế thừa hoàn toàn. Đây là công cụ giúp bảo vệ đoạn code quan trọng, vốn phải hoạt động chính xác như thiết kế.
Thử thách
DễHãy xây dựng một hệ thống quản lý tài liệu để minh họa cách từ khóa final bảo vệ chức năng quan trọng khỏi bị các lớp con sửa đổi.
Bạn sẽ tạo ba tệp phối hợp với nhau để quản lý các loại tài liệu khác nhau, đồng thời giữ nguyên một số tính năng bảo mật:
Document.php: Định nghĩa lớpDocumentlàm lớp cơ sở cho mọi tài liệu. Lớp này cần có thuộc tính công khai$titlevà thuộc tính bảo vệ$author. Hàm khởi tạo nhận cả tiêu đề và tác giả. Thêm một phương thứcfinalcó têngetSignature(), trả về"Signed by: [author]". Các lớp con không được thay đổi tính năng bảo mật này. Đồng thời, thêm phương thức thông thườnggetContent(), trả về"Document: [title]".Report.php: Định nghĩa lớpReportkế thừaDocument. Thêm tệp Document ở đầu tệp. Lớp này bổ sung thuộc tính$department. Hàm khởi tạo cần nhận tiêu đề, tác giả và phòng ban: dùngparent::__construct()cho hai giá trị đầu, sau đó gán phòng ban. Ghi đè phương thứcgetContent()để trả về"Report: [title] ([department])". LớpReportkế thừa phương thứcgetSignature()có từ khóa final mà không thể thay đổi phương thức này.main.php: Thêm tệp Report. Bạn sẽ nhận ba đầu vào: tiêu đề tài liệu, tên tác giả và phòng ban. Tạo một đối tượngReportvới các giá trị này. In kết quả củagetContent()ở dòng đầu tiên, sau đó in kết quả củagetSignature()ở dòng thứ hai.
Thử thách này cho thấy các phương thức final bảo vệ chức năng quan trọng như thế nào: việc tạo chữ ký luôn nhất quán với mọi loại tài liệu, trong khi mỗi lớp con có thể tùy chỉnh các phương thức khác như getContent(). Lớp Report có thể thay đổi cách hiển thị nội dung, nhưng lớp cha khóa định dạng chữ ký.
Tự làm thử
<?php
require_once 'Report.php';
// Đọc đầu vào
$title = trim(fgets(STDIN));
$author = trim(fgets(STDIN));
$department = trim(fgets(STDIN));
// TODO: Tạo đối tượng Report bằng các giá trị đầu vào
// TODO: In ra kết quả của getContent()
// TODO: In ra kết quả của getSignature()
?>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