PHP 5 introduce classi e metodi astratti. Le classi definite come astratte non possono essere istanziate, e qualsiasi classe che contenga almeno un metodo astratto deve anch'essa essere astratta. I metodi definiti come astratti dichiarano unicamente la propria firma - non possono dichiarare un'implementazione.
Quando ereditati da una classe astratta, tutti i metodi segnalati come astratti nella dichiarazione della classe padre devono essere definiti dalla classe figlio; inoltre, questi metodi devono essere definiti con la stessa or a visibilità (o con una meno ristretta). Per esempio, se il metodo astratto è definito come protetto, l'implementazione della funzione può essere definita come protetta o publica, ma non privata. Inoltre le firme dei metodi devono corrispondere, cioè il tipo e il numero degli argomenti richiesti deve essere lo stesso. Per esempio, se la classe figlio definisce un argomento opzionale, mentre la firma del metodo astratto non lo fa, non ci sono conflitti nella firma. Questo vale anche per i costruttori a partire da PHP 5.4. Prima della 5.4 le firme dei costruttori possono essere differenti.
Example #1 Esempio di classe astratta
<?php
abstract class AbstractClass
{
// Forza la classe estendente a definire questo metodo
abstract protected function getValue();
abstract protected function prefixValue($prefix);
// Metodi comuni
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";
?>
Il precedente esempio visualizzerà:
ConcreteClass1 FOO_ConcreteClass1 ConcreteClass2 FOO_ConcreteClass2
Example #2 Abstract class example
<?php
abstract class AbstractClass
{
// Il nostro metodo astratto ha solo bisogno di definire gli argomenti richiesti
abstract protected function prefixName($name);
}
class ConcreteClass extends AbstractClass
{
// La nostra classe figlio può definire argomenti opzionali non presenti nella firma del padre
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";
?>
Il precedente esempio visualizzerà:
Mr. Pacman Mrs. Pacwoman
Codice vecchio che non ha classi definite dall'utente o funzioni dichiarate come 'abstract' dovrebbe poter essere eseguito senza necessità di modifiche.