Abstração de Classes

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.