Sınıf Soyutlama

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.