Clase Abstracte

PHP 5 introduce clase și metode abstracte. Clasele definite ca abstracte nu pot fi instanțiate și orice clasă care conține cel puțin o metodă abstractă trebuie să fie și ea abstractă. Metodele abstracte declară doar semnătura unei metode și nu pot defini o implementare concretă.

La moștenirea dintr-o clasă abstractă, toate metodele abstracte din părinte trebuie implementate; în plus, aceste metode trebuie definite cu o vizibilitate identică (sau mai puțin restrictivă). De exemplu, dacă metoda este definită 'protected', implementarea concretă trebuie să definească funcția 'protected' sau 'public', dar nu 'private'. În plus, semnăturile metodelor trebuie să corespundă una alteia, adică sugestia tipului și numărul argumentelor necesare trebuie să fie aceleași. De exemplu, dacă clasa-fiică definește un argument opțional, în timp ce semnătura metodei abstracte nu definește, atunci nu este nici un conflict în semnătură. Aceasta la fel se aplică și la constructori începând cu PHP 5.4. Înainte de 5.4 semnăturile constructorilor puteau să difere.

Example #1 Exemplu de clasă abstractă

<?php
abstract class AbstractClass
{
    
// Forțează implementarea în copii a următoarelor metode
    
abstract protected function getValue();
    abstract protected function 
prefixValue($prefix);

    
// Metodă comună
    
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";
?>

Exemplul de mai sus va afișa:

ConcreteClass1
FOO_ConcreteClass1
ConcreteClass2
FOO_ConcreteClass2

Example #2 Exemplu cu clasă abstractă

<?php
abstract class AbstractClass
{
    
// Metoda noastră abstractă trebuie doar să definească argumentele necesare
    
abstract protected function prefixName($name);

}

class 
ConcreteClass extends AbstractClass
{

    
// Clasa noastră fiică poate defini argumente opționale care nu sunt prezente în semnătura părintelui
    
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";
?>

Exemplul de mai sus va afișa:

Mr. Pacman
Mrs. Pacwoman

Codul vechi care nu are nici o clasă sau funcție definită de utilizator cu numele 'abstract' ar trebui să funcționeze fără modificări.