O PHP 5 introduz métodos e classes abstratas. Classes definidas como abstratas não podem ser instanciadas, e qualquer classe que contenha ao menos um método abstrato também deve ser abstrata. Métodos são definidos como abstratos declarando a intenção em sua assinatura - não podem definir a implementação.
Ao herdar uma classe abstrata, todos os métodos marcados como abstratos na na declaração da classe pai devem ser implementados na classe filha; adicionalmente, estes métodos devem ser definidos com a mesma (ou menos restrita) visibilidade. Por exemplo, se um método abstrato for definido como protegido, a implementação da função deve ser definida como protegida ou pública, mas não privada. Além disso, a assina dos métodos devem coincidir, isso é, as induções de tipo e o número de argumentos exigidos devem ser os mesmos. Por exemplo, se a classe filha define um argumento opcional, e a assinatura do método abstrato não, há um conflito na assinatura. Também se aplica a construtores desde o PHP 5.4. Em versões anteriores a 5.4, as assinaturas dos construtores poderiam ser diferentes.
Exemplo #1 Exemplo de classe abstrata
<?php
abstract class ClasseAbstrata
{
// Força a classe que estende ClasseAbstrata a definir esse método
abstract protected function pegarValor();
abstract protected function valorComPrefixo( $prefixo );
// Método comum
public function imprimir() {
print $this->pegarValor();
}
}
class ClasseConcreta1 extends ClasseAbstrata
{
protected function pegarValor() {
return "ClasseConcreta1";
}
public function valorComPrefixo( $prefixo ) {
return "{$prefixo}ClasseConcreta1";
}
}
class ClasseConcreta2 extends ClasseAbstrata
{
protected function pegarValor() {
return "ClasseConcreta2";
}
public function valorComPrefixo( $prefixo ) {
return "{$prefixo}ClasseConcreta2";
}
}
$classe1 = new ClasseConcreta1;
$classe1->imprimir();
echo $classe1->valorComPrefixo('FOO_') ."\n";
$classe2 = new ClasseConcreta2;
$classe2->imprimir();
echo $classe2->valorComPrefixo('FOO_') ."\n";
?>
O exemplo acima irá imprimir:
ConcreteClass1 FOO_ConcreteClass1 ConcreteClass2 FOO_ConcreteClass2
Exemplo #2 Exemplo de classe abstrata
<?php
abstract class ClasseAbstrata
{
// Esse método abstrato apenas define os argumentos requeridos
abstract protected function prefixName($name);
}
class ClasseConcreta extends ClasseAbstrata
{
// O método filho pode definir argumentos opcionais não presentes na assitura abstrata
public function prefixName($name, $separator = ".") {
if ($name == "Pacman") {
$prefix = "Mr";
} elseif ($name == "Pacwoman") {
$prefix = "Mrs";
} else {
$prefix = "";
}
return "{$prefix}{$separator} {$name}";
}
}
$class = new ClasseConcreta;
echo $class->prefixName("Pacman"), "\n";
echo $class->prefixName("Pacwoman"), "\n";
?>
O exemplo acima irá imprimir:
Mr. Pacman Mrs. Pacwoman
Códigos antigos que não possuem classes e funções com nome 'abstract' podem ser executados sem modificações.