[Bài đọc] Class Abstraction
NỘI DUNG BÀI VIẾT
PHP5 đưa vào khái niệm lớp trừu tượng (abstract class) cùng các phương thức trừu tượng (abstract method). Lớp trừu tượng được định nghĩa ra không nhằm cho việc sử dụng để tạo ra đối tượng từ nó, lớp trừu có ít nhất một phương thức trừu tượng phải được định nghĩa là một abstract class. Các phương thức trừu tượng chỉ cần khai báo tên phương thức và danh sách tham số (signature của phương thức ) chứ không định nghĩa thành phần thực thi bên trong (không có phần thân giống như các phương thức của interface).
Khi một lớp kế thừa một lớp trừu tượng, nó phải định nghĩa (triển khai) toàn bộ các phương thức trừu tượng ở lớp trừu tượng mà nó kế thừa; hơn nữa, các phương thức phải được định nghĩa mức độ visibility cùng hoặc cao hơn mức visibility đã chỉ định trong lớp cha (public, private, protected).
Ví dụ, nếu chúng ta định nghĩa tại lớp trừu tượng cha một phương thức trừu tượng với có mức visibility là protected, thì khi triển khai ở lớp con chúng ta phải giữ nguyên mức visibility là protected hoặc nâng lên mức cao hơn là public, chứ không thể để là private. Ngoài nguyên mẫu (signature) của những phương thức đó phải trùng khớp với nhau, tức là tên phương thức, số lượng tham số, kiểu dữ liệu của các tham số và trình tự các tham số phải giống nhau. Ví dụ, nếu lớp con khai báo một tham số đầu vào tuỳ chọn nhưng khi đó phương thức trừu tượng ở lớp cha không hỗ trợ nó, chắc chắn sẽ gây ra xung đột trong việc thực thi. Lớp trừu tượng cũng sử dụng hàm tạo (constructor) từ phiên bản PHP5.4. Các bản trước đó có sự khác biệt về hàm tạo.
Ví dụ 1: Lớp trừu tượng
<?php abstract class AbstractClass { // Các lớp kế thừa bắt buộc phải cài đặt các phương thức này abstract protected function getValue(); abstract protected function prefixValue($prefix); // Phương thức thông thường public function printOut() { print $this->getValue() . "\n"; } } class ConcreteClass1 extends AbstractClass { protected function getValue() { return "ConcreteClass1"; } public function prefixValue($prefix) { return "{$prefix}ConcreteClass1"; } } class ConcreteClass2 extends AbstractClass { public function getValue() { return "ConcreteClass2"; } public function prefixValue($prefix) { return "{$prefix}ConcreteClass2"; } } $class1 = new ConcreteClass1; $class1->printOut(); echo $class1->prefixValue('FOO_') ."\n"; $class2 = new ConcreteClass2; $class2->printOut(); echo $class2->prefixValue('FOO_') ."\n"; ?>
Chúng ta sẽ có kết quả từ đoạn mã trên như sau:
ConcreteClass1 FOO_ConcreteClass1 ConcreteClass2PHP5 đưa vào khái niệm lớp trừu tượng (abstract class) cùng các phương thức trừu tượng (abstract method). Lớp trừu tượng được định nghĩa ra không nhằm cho việc sử dụng để tạo ra đối tượng từ nó, lớp trừu có ít nhất một phương thức trừu tượng phải được định nghĩa là một abstract class. Các phương thức trừu tượng chỉ cần khai báo tên phương thức và danh sách tham số (signature của phương thức ) chứ không định nghĩa thành phần thực thi bên trong (không có phần thân giống như các phương thức của interface). Khi một lớp kế thừa một lớp trừu tượng, nó phải định nghĩa (triển khai) toàn bộ các phương thức trừu tượng ở lớp trừu tượng mà nó kế thừa; hơn nữa, các phương thức phải được định nghĩa mức độ visibility cùng hoặc cao hơn mức visibility đã chỉ định trong lớp cha (public, private, protected). Ví dụ, nếu chúng ta định nghĩa tại lớp trừu tượng cha một phương thức trừu tượng với có mức visibility là protected, thì khi triển khai ở lớp con chúng ta phải giữ nguyên mức visibility là protected hoặc nâng lên mức cao hơn là public, chứ không thể để là private. Ngoài nguyên mẫu (signature) của những phương thức đó phải trùng khớp với nhau, tức là tên phương thức, số lượng tham số, kiểu dữ liệu của các tham số và trình tự các tham số phải giống nhau. Ví dụ, nếu lớp con khai báo một tham số đầu vào tuỳ chọn nhưng khi đó phương thức trừu tượng ở lớp cha không hỗ trợ nó, chắc chắn sẽ gây ra xung đột trong việc thực thi. Lớp trừu tượng cũng sử dụng hàm tạo (constructor) từ phiên bản PHP5.4. Các bản trước đó có sự khác biệt về hàm tạo. Ví dụ 1: Lớp trừu tượng getValue() . "\n"; } } class ConcreteClass1 extends AbstractClass { protected function getValue() { return "ConcreteClass1"; } public function prefixValue($prefix) { return "{$prefix}ConcreteClass1"; } } class ConcreteClass2 extends AbstractClass { public function getValue() { return "ConcreteClass2"; } public function prefixValue($prefix) { return "{$prefix}ConcreteClass2"; } } $class1 = new ConcreteClass1; $class1->printOut(); echo $class1->prefixValue('FOO_') ."\n"; $class2 = new ConcreteClass2; $class2->printOut(); echo $class2->prefixValue('FOO_') ."\n"; ?> Chúng ta sẽ có kết quả từ đoạn mã trên như sau: ConcreteClass1 FOO_ConcreteClass1 ConcreteClass2 FOO_ConcreteClass2 Ví dụ 2: Lớp trừu tượng <?php abstract class AbstractClass { // Our abstract method only needs to define the required arguments abstract protected function prefixName($name); } class ConcreteClass extends AbstractClass { // Our child class may define optional arguments not in the parent's signature public function prefixName($name, $separator = ".") { if ($name == "Pacman") { $prefix = "Mr"; } elseif ($name == "Pacwoman") { $prefix = "Mrs"; } else { $prefix = ""; } return "{$prefix}{$separator} {$name}"; } } $class = new ConcreteClass; echo $class->prefixName("Pacman"), "\n"; echo $class->prefixName("Pacwoman"), "\n"; ?> Kết quả của đoạn mã trên như sau: Mr. Pacman Mrs. Pacwoman Đoạn mã cũ như các lớp hoặc hàm không được người dùng quy định là ‘abstract’ có thể chạy mà không cần chỉnh sửa. Bài viết được dịch từ :http://php.net FOO_ConcreteClass2
Ví dụ 2: Lớp trừu tượng
<?php abstract class AbstractClass { // Our abstract method only needs to define the required arguments abstract protected function prefixName($name); } class ConcreteClass extends AbstractClass { // Our child class may define optional arguments not in the parent's signature public function prefixName($name, $separator = ".") { if ($name == "Pacman") { $prefix = "Mr"; } elseif ($name == "Pacwoman") { $prefix = "Mrs"; } else { $prefix = ""; } return "{$prefix}{$separator} {$name}"; } } $class = new ConcreteClass; echo $class->prefixName("Pacman"), "\n"; echo $class->prefixName("Pacwoman"), "\n"; ?>
Kết quả của đoạn mã trên như sau:
Mr. Pacman Mrs. Pacwoman
Đoạn mã cũ như các lớp hoặc hàm không được người dùng quy định là ‘abstract’ có thể chạy mà không cần chỉnh sửa.
Bài viết được dịch từ :http://php.net
Leave a Reply