PHP也支援抽象類的和抽象方法,被定義為抽象類的方法不能被實體化,在任何一個類別中,
如果他至少有一個方法被聲明為抽象,那這個類必須要被聲明為抽象類。被定義為抽象類的方法只能聲明他該怎麼使用,不能定義具體功能實現。
當有類別繼承抽象類別時,子類別必須要定義父類別中的所以抽象方法,另外,這些方法的訪問控制必須和父類中一樣(或者更為寬鬆)。例如某個抽象方法是被聲明為受保護的,那麼子類中實現的方法就應該聲明為受保護的或者公有的,而不能定義為私有的。
此外方法的調用方式必須匹配,即類型和所需參數數量必須一致。例如,子類定義了一個可選參數,而父類抽象方法的聲明里沒有,則兩者的聲明並無衝突。
這也適用於 PHP 5.4 起的構造函數。在 PHP 5.4 之前的構造函數聲明可以不一樣的。
<?php
abstract class AbstractClass
{
// 子類必須定義這些方法,否則會出錯
abstract protected function getValue();
abstract protected function prefixValue($prefix);
// 普通方法(非抽象方法)
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";
?>
// outputs
// ConcreteClass1
// FOO_ConcreteClass1
// ConcreteClass2
// FOO_ConcreteClass2
<?php
abstract class AbstractClass
{
// 我们的抽象方法仅需要定义需要的参数
abstract protected function prefixName($name);
}
class ConcreteClass extends AbstractClass
{
// 子類的方法可以定義父類方法中不存在的可選參數,不衝突
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";
?>
// outputs
// Mr. Pacman
// Mrs. Pacwoman
資料來源: https://www.php.net/