Phương thức trừu tượng trong đặ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 54 trên 91.
Trait có thể cung cấp các phương thức dùng ngay, nhưng đôi khi bạn cần lớp sử dụng trait triển khai chức năng cụ thể. Khi đó, phương thức trừu tượng trong trait sẽ hữu ích: chúng định nghĩa một hợp đồng mà lớp sử dụng trait phải thực hiện.
Khi một trait khai báo một phương thức trừu tượng, mọi lớp dùng trait đó phải triển khai phương thức ấy:
<?php
trait Notifiable {
abstract public function getEmail(): string;
public function sendNotification(string $message): void {
echo "Sending to " . $this->getEmail() . ": $message";
}
}
class User {
use Notifiable;
public function __construct(private string $email) {}
public function getEmail(): string {
return $this->email;
}
}
$user = new User("john@example.com");
$user->sendNotification("Welcome!");
Đầu ra:
Sending to john@example.com: Welcome!Trait cung cấp phương thức sendNotification() nhưng cần lớp tự triển khai getEmail(). Cách này tạo nên một mô hình mạnh mẽ, trong đó trait xử lý logic chung còn lớp triển khai đảm nhiệm các chi tiết riêng.
Nếu một lớp sử dụng trait mà không triển khai phương thức trừu tượng, PHP sẽ báo lỗi nghiêm trọng. Điều này giúp trait có thể dựa vào sự tồn tại của một số phương thức, nhờ đó code của bạn dễ dự đoán và dễ bảo trì hơn.
Thử thách
DễHãy xây dựng một hệ thống định giá, trong đó các loại sản phẩm khác nhau tính giá cuối cùng theo cách khác nhau, nhưng đều dùng chung logic giảm giá thông qua một trait có phương thức trừu tượng.
Bạn sẽ tổ chức code trong ba tệp:
Discountable.php: Tạo một trait tên làDiscountableđể cung cấp chức năng giảm giá. Trait này cần có:- Một phương thức trừu tượng
getBasePrice(): floatmà các lớp sử dụng trait này phải triển khai - Một phương thức
applyDiscount(int $percent)để tính và trả về giá sau khi áp dụng phần trăm giảm giá cho giá gốc - Một phương thức
getFinalPrice(int $percent)để trả về chuỗi đã định dạng:"Final price: $[discounted_price]"với 2 chữ số thập phân
- Một phương thức trừu tượng
Product.php: Tạo một lớpProductsử dụng traitDiscountable. Thêm tệp trait vào. Dùng tính năng thăng cấp thuộc tính hàm khởi tạo để khai báo một$nameriêng tư (chuỗi) và một$priceriêng tư (số thực). Triển khai phương thứcgetBasePrice()cần thiết để trả về giá của sản phẩm.main.php: Thêm tệp Product vào. Bạn sẽ nhận ba đầu vào: tên sản phẩm, giá và phần trăm giảm giá. Tạo một đối tượngProductvà in ra hai dòng:- Giá gốc được định dạng như
"Base: $[price]"với 2 chữ số thập phân - Kết quả gọi
getFinalPrice()với phần trăm giảm giá
- Giá gốc được định dạng như
Mẫu này rất hữu ích vì mọi lớp đều có thể dùng trait Discountable, chẳng hạn như sản phẩm, dịch vụ và gói đăng ký, miễn là chúng triển khai getBasePrice(). Trait cung cấp logic giảm giá dùng chung, còn mỗi lớp xác định giá gốc của mình lấy từ đâu.
Tự làm thử
<?php
require_once 'Product.php';
// Đọc các đầu vào
$name = trim(fgets(STDIN));
$price = floatval(trim(fgets(STDIN)));
$discountPercent = intval(trim(fgets(STDIN)));
// TODO: Tạo một instance của Product với tên và giá
// TODO: In ra giá gốc theo định dạng "Base: $[price]" với 2 chữ số thập phân
// TODO: In ra kết quả gọi getFinalPrice() với phần trăm giảm giá
?>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