PHP 5, soyut sınıf ve yöntemlerin kullanımını mümkün kılmıştır. Soyut olarak tanımlanmış bir sınıf örneklenemeyebilir ve en az bir soyut yöntem içeren bir sınıf da soyut olmalıdır. Soyut olarak tanımlanmış yöntemler o yöntemlerin imzasıdırlar, gerçeklemenin bütününü temsil edemezler.
Soyut bir sınıftan kalıtsal özellikler devralınırken, ebeveyn sınıf
bildiriminde soyut olarak bildirilmiş tüm yöntemlerin çocuk sınıf
tarafından da tanımlanması gerekir. Ek olarak, bu yöntemlerin aynı (ya da
daha az sınırlı) görünürlükle tanımlanması gerekir. Örneğin, soyut yöntem
protected
olarak tanımlanmışsa, işlev gerçeklenimi
private
değil, protected
ya da
public
olarak tanımlanmalıdır. Bundan başka, yöntemlerin
imzaları da eşleşmelidir, örneğin gerekli değiştirgelerin tür ipuçları
ve sayıları aynı olmalıdır. Örneğin bir çocuk sınıf seçimlik bir
değiştirge tanımlarken soyut yöntem bunu yapmıyorsa bir imza uyumsuzluğu
yoktur. PHP5.4'te bu kuruculara da uygulanır. PHP 5.4 öncesinde kurucu
imzaları farklı olabilirdi.
Örnek 1 - Soyut sınıf örneği
<?php
abstract class SoyutSınıf
{
// Genişletilen sınıfı bu yöntemi tanımlamaya zorla
abstract protected function değeriAl();
abstract protected function önekDeğeri($önek);
// Ortak yöntem
public function yazdır() {
print $this->değeriAl() . "\n";
}
}
class SomutSınıf1 extends SoyutSınıf
{
protected function değeriAl() {
return "SomutSınıf1";
}
public function önekDeğeri($önek) {
return "{$önek}SomutSınıf1";
}
}
class SomutSınıf2 extends SoyutSınıf
{
public function değeriAl() {
return "SomutSınıf2";
}
public function önekDeğeri($önek) {
return "{$önek}SomutSınıf2";
}
}
$class1 = new SomutSınıf1;
$class1->yazdır();
echo $class1->önekDeğeri('FOO_') ."\n";
$class2 = new SomutSınıf2;
$class2->yazdır();
echo $class2->önekDeğeri('FOO_') ."\n";
?>
Yukarıdaki örneğin çıktısı:
SomutSınıf1 FOO_SomutSınıf1 SomutSınıf2 FOO_SomutSınıf2
Örnek 2 Soyut sınıf örneği
<?php
abstract class AbstractClass
{
// Soyut sınıfımız sadece gerekli değiştirgeleri tanımlamalı
abstract protected function prefixName($name);
}
class ConcreteClass extends AbstractClass
{
// Çocuk sınıfımız seçimlik değiştirgeleri tanımlamalı
// ebeveynin imzasındakileri değil
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";
?>
Yukarıdaki örneğin çıktısı:
Mr. Pacman Mrs. Pacwoman
Kullanıcı tanımlı sınıfları veya 'abstract' isimli işlevleri olmayan eski kodun bir değişikliğe gerek duyulmadan çalışabilmesi gerekir.