Como você não sabe o tipo (classname) dos objetos retornados antes de fazer a consulta, não pode especificá-lo.
No entanto, você pode encapsular essa lógica dentro de outro tipo que você usa como tipo de retorno que pode retornar o tipo de retorno específico:
/**
* Should not have any private, public or protected members in it's definition.
*
* Does only work for public properties.
*/
class ReturnObject {
public function getConcrete()
{
/* decide here which class */
$classname = 'Child'; // or 'Adult'
return $this->selfAs($classname);
}
private function selfAs($classname)
{
$l = strlen(__CLASS__);
$s = sprintf('O:%d:"%s"', strlen($classname), $classname).substr(serialize($this), 5+strlen($l)+$l);
$instance = unserialize($s);
$instance->__construct();
return $instance;
}
}
Você pode então usar o
getConcrete()
função em cada objeto retornado para retornar seu tipo específico, sua lógica de decisão vinculada ao retorno do banco de dados. Editar: Eu mudei para uma versão que inicializará primeiro as propriedades dos objetos via unserialize (por favor, teste se isso funciona, é baseado na suposição de que estamos falando apenas de propriedades públicas e não sei se o PDO apenas faz os setters ou mais via reflexão no modo que você está usando) e, em seguida, chama a função construtora. O construtor precisa ser público (e deve existir) para que isso funcione.
É tecnicamente possível disponibilizar isso também para membros privados e protegidos, no entanto, isso precisa de reflexão real e também precisa de análise dos dados serializados. Esta classe apenas renomeia o nome da classe, mas não dentro de propriedades privadas.
No entanto, esta é apenas uma maneira de fazê-lo. Você provavelmente só precisa de um
->isChild()
ou ->isAdult()
função em sua Person
classe.