PHP: Trừu tượng (Abstract)
Giải phóng thời gian, khai phóng năng lực
Tổng quan
Từ phiên bản PHP 5 thì PHP giới thiệu các khái niệm lớp trừu tượng và phương thức trừu tượng. Những lớp được định nghĩa là trừu tượng thì không được có thể hiện (không tạo được thể hiện hay đối tượng của lớp trừu tượng), và bất kỳ lớp nào chứa ít nhất một phương thức trừu tượng thì phải là lớp trừu tượng. Đối với phương thức trừu tượng thì ta chỉ khai báo mà không được định nghĩa.
Các lớp khác có quyền thừa kế từ lớp trừu tượng. Khi thừa kế từ lớp trừu tượng thì tất cả các phương thức trừu tượng của lớp cha phải được lớp con thực thi (định nghĩa); một điểm nữa là những phương thức này phải được định nghĩa với tầm vực tương tự (không thấp hơn) hoặc cao hơn. Ví dụ như nếu phương thức trừu tượng được định nghĩa là protected thì việc thực thi phương thức này ở lớp con cũng phải được định nghĩa là protected hoặc cao hơn (public). Tuy vậy, bạn lại không cần thực thi phương thức ở lớp con với các dấu hiệu (signature) phải y hệt như của phương trừu tượng ở lớp cha, tức là bạn có quyền đưa thêm đối số tùy chọn vào phương thức thực thi ở lớp con nếu bạn muốn. Đặc điểm này cũng được áp dụng cho các hàm tạo.
Để định nghĩa một lớp nào đó là trừu tượng ta thêm từ khóa abstract vào trước từ khóa class của lớp đó.
Còn để khai báo một phương thức nào đó là trừu tượng ta thêm từ khóa abstract vào trước từ khóa function hoặc trước tầm vực (nếu có) của phương thức đó. Dưới đây là những ví dụ về cách sử dụng abstract.
Ví dụ 1:
<?php
abstract class AbstractClass
{
// Những phương thức trừu tượng này phải được thực thi ở lớp thừa kế
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";
?>
Ví dụ trên sẽ in ra:
FOO_ConcreteClass1
ConcreteClass2
FOO_ConcreteClass2
Ví dụ 2:
<?php
abstract class AbstractClass
{
// Phương thức trừu tượng này có một đối số
abstract protected function prefixName($name);
}
class ConcreteClass extends AbstractClass
{
// Ta có quyền thực thi phương thức trừu tượng ở lớp con với đối số tùy chọn
// mà không có trong phương thức trừu tượng của lớp cha
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";
?>
Ví dụ trên sẽ in ra:
Mrs. Pacwoman
Giải phóng thời gian, khai phóng năng lực