No artigo anterior foi mostrado como simular sobrecarga de métodos baseada no tipo de variável a ser recebida como parâmetro. Conforme previsto anteriormente, agora veremos como fazer esse tratamento com objetos ao invés de variáveis simples.
Exemplo
Voltamos ao já tradicional exemplo da Escola. Suponha que você esteja trabalhando em um sistema de gerenciamento de uma Escola, e queira criar um método para cadastrar um usuário em seu sistema, porém existem diversos tipos de usuários. Você pode ter criado uma superclasse chamada Pessoa e depois criou suas derivadas como Professor e Aluno. Apesar de possuírem características em comum (por isso você possui a superclasse Usuario), para cadastrá-los você precisa realizar algumas tarefas específicas.
Para o Professor:
-inserí-lo no quadro de funcionários
-cadastrar as matérias que ele leciona
-cadastrar as turmas onde ele leciona
Para o Aluno:
-gerar seu número de matrícula
-inserí-lo em uma turma
Além dessas tarefas específicas, você pode também querer notificar a pessoa cadastrada através do envio de um e-mail com todos os seus dados de acesso. Note que essa é uma operação genérica, e ela é realizada para Professores e para Alunos.
Como isso pode ser feito?
Agora entramos novamente no conceito de criar um método de “fachada” para a operação de inserção. Dentro da classe responsável pelo gerenciamento de usuários, você pode criar os seguintes métodos na classe de gerenciamento de usuários:
GerenciadorUsuarios
public inserirUsuario(objeto) método que servirá de “fachada” para inserir um usuário
private _inserirProfessor(objProfessor) realiza todas as tarefas para inserir um professor no sistema
private _inserirAluno(objAluno) realiza todas as tarefas para inserir um aluno no sistema
Quanto à classe Pessoa, ela será a base para Aluno e Professor, por isso deve conter apenas informações comuns à ambas. Neste caso, apenas o método enviarDados().
Pessoa
public enviarDados() envia os dados de acesso ao sistema para o e-mail do usuário
A classe Professor irá herdar o método enviarDados() da classe Pessoa, por isso deverá conter apenas suas operações específicas.
Professor
public cadastrarMaterias() cadastra as matérias que serão lecionadas pelo professor
public cadastrarTurmas() cadastra as turmas onde o professor irá lecionar
O mesmo ocorre com Aluno.
Aluno
public gerarMatricula() matricula o Aluno
public cadastrarEmTurma() cadastra o Aluno em uma turma ativa
Finalmente o código!
A parte que realmente nos interessa se encontra na classe GerenciadorUsuarios, pois é nela que está o “truque”.
class GerenciadorUsuarios {
/**
* Note que foi passado como parâmetro um objeto genérico
* chamado objNovoUsuario. Apenas dentro da função
* será feito o tratamento necessário para definir as ações
* a serem tomadas de acordo com o tipo de objeto
* recebido (Aluno/Professor).
*/
function inserirUsuario(objNovoUsuario) {
/**
* O operador instanceof checa se o objeto é uma instância
* de determinada classe.
*/
if (objNovoUsuario instanceof Professor) {
this->_inserirProfessor(objNovoUsuario);
} else if (objNovoUsuario instanceof Aluno) {
this->_inserirAluno(objNovoUsuario);
} else {
echo "Erro ao inserir usuário!\n";
return false;
}
/**
* Como este é um método comum às classes
* Professor e Aluno, ele deve ser chamado após
* a verificação de tipo, para ser executado em
* ambos os casos.
*/
objNovoUsuario->enviarDados();
}
/**
* Este é o método que irá realizar a chamada aos
* métodos da classe Professor. Ele só é chamado
* quando o usuário a ser inserido foi identificado
* como sendo da classe Professor.
*/
private function _inserirProfessor(Professor objProfessor) {
echo "Inserindo Professor!\n";
objProfessor->cadastrarMateria();
objProfessor->cadastrarTurma();
echo "\n";
}
/**
* Este método fará a chamada aos métodos
* da classe Aluno. Ele só é chamado quando
* o usuário a ser inserido foi identificado
* como sendo da classe Aluno.
*/
private function _inserirAluno(Aluno objAluno) {
echo "Inserindo Aluno!\n";
objAluno->gerarMatricula();
objAluno->cadastrarEmTurma();
echo "\n";
}
}
Basicamente o que nos interessa é apenas a verificação feita no método inserirUsuário(), pois com isso é possível inserir Professores e Alunos chamando o mesmo método.
Testando o Código
Para testar o funcionamento do código, podemos utilizar:
objGerenciador = new GerenciadorUsuarios;
objAluno = new Aluno();
objProfessor = new Professor();
objGerenciador->inserirUsuario(objAluno);
objGerenciador->inserirUsuario(objProfessor);
Com isso devemos obter como saída:
- Inserindo Aluno!
- Aluno matriculado!
- Aluno cadastrado em turma!
- Inserindo Professor!
- Matéria cadastrada!
- Turma cadastrada!
Finalizando…
Creio que este exemplo ficou um pouco extenso, mas quis demonstrar uma aplicação pelo menos próxima de uma situação real em um sistema. Todo o código PHP utilizado para criar este exemplo pode ser baixado no link logo abaixo.
Na próxima (e última) parte dessa série de artigos, irei abordar uma outra maneira de simular sobrecarga no PHP, utilizando o método mágico __call().
Espero ter contribuído para sua programação!
Downloads
Código PHP (exemplo):