Menu
CoddyTech

Lớp trừu tượng

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 25 trên 91.

Lớp trừu tượng là lớp không thể được khởi tạo trực tiếp. Lớp này làm khuôn mẫu cho các lớp khác, định nghĩa những phương thức mà các lớp con phải triển khai. Bạn tạo lớp trừu tượng bằng từ khóa abstract.

<?php
abstract class Shape {
    protected $color;
    
    public function __construct($color) {
        $this->color = $color;
    }
    
    abstract public function calculateArea();
    
    public function getColor() {
        return $this->color;
    }
}

class Rectangle extends Shape {
    private $width;
    private $height;
    
    public function __construct($color, $width, $height) {
        parent::__construct($color);
        $this->width = $width;
        $this->height = $height;
    }
    
    public function calculateArea() {
        return $this->width * $this->height;
    }
}

$rect = new Rectangle("blue", 5, 3);
echo $rect->calculateArea();

Đầu ra:

15

Lớp Shape khai báo một phương thức trừu tượng calculateArea() nhưng không cung cấp phần triển khai. Mọi lớp kế thừa Shape đều phải triển khai phương thức này. Lưu ý rằng lớp trừu tượng cũng có thể chứa các phương thức thông thường như getColor() để các lớp con kế thừa trực tiếp.

Phương thức trừu tượng định nghĩa việc lớp con phải làm, nhưng không quy định cách thực hiện. Nhờ vậy, mọi hình đều có phương thức calculateArea(), đồng thời mỗi hình có thể tính diện tích theo cách khác nhau.

Điểm chính: Lớp trừu tượng kết hợp cấu trúc kế thừa với các yêu cầu bắt buộc. Hãy dùng lớp trừu tượng khi bạn muốn chia sẻ code giữa các lớp có liên quan, đồng thời đảm bảo mỗi lớp con đều triển khai một số phương thức nhất định.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống phát nội dung đa phương tiện để minh họa cách lớp trừu tượng áp đặt một giao ước, đồng thời cho phép các loại nội dung đa phương tiện khác nhau tự triển khai cách phát riêng.

Bạn sẽ sắp xếp code trong ba tệp:

  • Media.php: Định nghĩa lớp trừu tượng Media, đóng vai trò làm khuôn mẫu cho mọi loại nội dung đa phương tiện. Lớp này cần có thuộc tính $title với phạm vi protected và một hàm khởi tạo nhận rồi thiết lập tiêu đề. Thêm phương thức trừu tượng có tên play() mà các lớp con phải triển khai. Đồng thời, thêm phương thức thông thường getTitle() trả về tiêu đề. Các lớp con sẽ kế thừa phương thức cụ thể này.
  • Song.php: Định nghĩa lớp Song kế thừa Media. Thêm tệp Media ở đầu tệp. Lớp này bổ sung thuộc tính $artist. Hàm khởi tạo cần nhận tiêu đề và nghệ sĩ: dùng parent::__construct() cho tiêu đề, sau đó tự thiết lập nghệ sĩ. Triển khai phương thức bắt buộc play() để trả về "Playing song: [title] by [artist]".
  • Podcast.php: Định nghĩa lớp Podcast kế thừa Media. Thêm tệp Media ở đầu tệp. Lớp này bổ sung thuộc tính $episode (một số nguyên). Hàm khởi tạo cần nhận tiêu đề và số tập: dùng parent::__construct() cho tiêu đề, sau đó thiết lập số tập. Triển khai phương thức bắt buộc play() để trả về "Playing podcast: [title] - Episode [episode]".

Trong main.php, thêm cả hai tệp Song và Podcast. Bạn sẽ nhận bốn đầu vào: tiêu đề bài hát, tên nghệ sĩ, tiêu đề podcast và số tập (dưới dạng chuỗi cần chuyển thành số nguyên). Tạo một đối tượng Song và một đối tượng Podcast với các giá trị này. In kết quả gọi play() trên bài hát trước, rồi đến podcast, mỗi kết quả trên một dòng riêng.

Thử thách này cho thấy cách lớp trừu tượng định nghĩa một giao ước: mọi loại nội dung đa phương tiện đều phải có phương thức play(), nhưng mỗi loại triển khai phương thức đó theo cách khác nhau. Không thể tạo đối tượng trực tiếp từ lớp trừu tượng Media; lớp này chỉ tồn tại để cung cấp cấu trúc và chức năng dùng chung cho các lớp con.

Tự làm thử

<?php
require_once 'Song.php';
require_once 'Podcast.php';

// Đọc dữ liệu đầu vào
$songTitle = trim(fgets(STDIN));
$artistName = trim(fgets(STDIN));
$podcastTitle = trim(fgets(STDIN));
$episodeNumber = intval(trim(fgets(STDIN)));

// TODO: Tạo đối tượng Song với songTitle và artistName

// TODO: Tạo đối tượng Podcast với podcastTitle và episodeNumber

// TODO: In ra kết quả khi gọi play() trên bài hát

// TODO: In ra kết quả khi gọi play() trên podcast

?>
quiz iconTự kiểm tra

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

Tự luyện tập: Trình biên dịch PHP online