Giới thiệu về đặc tính
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 51 trên 91.
PHP chỉ hỗ trợ kế thừa đơn, một lớp chỉ có thể mở rộng một lớp cha. Nhưng nếu bạn cần chia sẻ chức năng giữa nhiều lớp không liên quan thì sao? Đây là lúc trait phát huy tác dụng.
Trait là một cơ chế tái sử dụng code, cho phép bạn định nghĩa các phương thức và thuộc tính để đưa vào nhiều lớp. Hãy xem trait như thao tác sao chép và dán ở cấp độ ngôn ngữ: code trong trait trở thành một phần của lớp sử dụng nó.
<?php
trait Timestampable {
private string $createdAt;
public function setCreatedAt(): void {
$this->createdAt = date('Y-m-d H:i:s');
}
public function getCreatedAt(): string {
return $this->createdAt;
}
}
class Article {
use Timestampable;
public function __construct(public string $title) {
$this->setCreatedAt();
}
}
$article = new Article("PHP Traits");
echo $article->getCreatedAt();
Từ khóa use bên trong lớp sẽ nhập các thành phần của trait. Giờ đây, Article có thể dùng setCreatedAt() và getCreatedAt() như thể chúng được định nghĩa trực tiếp trong lớp.
Cùng một trait có thể dùng trong các lớp hoàn toàn không liên quan đến nhau, chẳng hạn như lớp Comment, lớp User hoặc bất kỳ lớp nào khác cần chức năng dấu thời gian. Cách này khắc phục hạn chế của kế thừa đơn bằng cách cho phép chia sẻ code theo chiều ngang trong hệ thống phân cấp lớp của bạn.
Thử thách
DễHãy xây dựng một hệ thống chào hỏi đơn giản để minh họa cách trait cho phép bạn dùng chung chức năng giữa các lớp không liên quan. Bạn sẽ tạo một trait cung cấp khả năng chào hỏi, sau đó dùng trait đó trong hai lớp hoàn toàn khác nhau.
Bạn sẽ sắp xếp code trong ba tệp:
Greetable.php: Tạo trait có tênGreetableđể cung cấp chức năng chào hỏi. Trait cần có:- Một thuộc tính riêng tư
$greeting(chuỗi) - Một phương thức
setGreeting(string $greeting)để lưu lời chào - Một phương thức
greet()trả về lời chào
- Một thuộc tính riêng tư
Person.php: Tạo lớpPersonsử dụng traitGreetable. Thêm tệp trait và dùng tính năng khai báo thuộc tính trong hàm khởi tạo để định nghĩa thuộc tính công khai$name. Trong hàm khởi tạo, gọisetGreeting()để đặt lời chào thành"Hello, I'm [name]".Robot.php: Tạo lớpRobotcũng sử dụng traitGreetable. Thêm tệp trait và dùng tính năng khai báo thuộc tính trong hàm khởi tạo để định nghĩa thuộc tính công khai$model. Trong hàm khởi tạo, gọisetGreeting()để đặt lời chào thành"Beep boop, I am model [model]".
Trong main.php, thêm cả hai tệp lớp. Bạn sẽ nhận được hai đầu vào: tên một người và số model của một robot. Tạo đối tượng từ cả hai lớp và in lời chào của chúng trên các dòng riêng biệt.
Điều này cho thấy sức mạnh của trait: Person và Robot là hai lớp hoàn toàn không liên quan, không có lớp cha chung, nhưng cả hai đều có cùng chức năng chào hỏi nhờ trait. Mỗi lớp tùy chỉnh cách sử dụng chức năng đó theo cách riêng.
Tự làm thử
<?php
require_once 'Person.php';
require_once 'Robot.php';
// Đọc đầu vào
$name = trim(fgets(STDIN));
$model = trim(fgets(STDIN));
// TODO: Tạo một instance Person với tên đã cho
// TODO: Tạo một instance Robot với mẫu đã cho
// TODO: In ra lời chào của Person
// TODO: In ra lời chào của Robot trên dòng mới
?>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án9Đặc tính
Giới thiệu về đặc tínhSử dụng nhiều đặc tínhGiải quyết xung đột giữa các đặc tínhPhương thức trừu tượng trong đặc tínhĐặc tính và kế thừaTự luyện tập: Trình biên dịch PHP online