Olá, estou tentando implementar no PHP algo como o código abaixo. Eu tenho uma classe pai de formulario, e tenho as classes filhas q são heranças desta. nas classes filhas eu nao tenho implementado o metodo save() esse método é exclusivo no pai, nas filhas tenho apenas e alternativamente os métodos before ou after save. Porém essas duas classes ja estao implementadas na classe pai, elas existem ali apenas para nao gerar erro de execucao quando o metodo save chama before ou after_save. Ou seja, se eu quiser nas classes filhas eu implemento ou nao os métodos before e after_save.
Pois bem o problema acontece quando eu declaro esses métodos na classe filha, ao instanciar as classes filhas e invocar os métodos before ou after_save, os metodos executados são os que se encontram na classe pai, pq o método save() esta na classe pai e este é quem está invocando os métodos.
Pergunta, como fazer para a classe pai executar os métodos que estão implementados na classe filha?
Vejam bem, não quero ser obrigado a escrever esses dois métodos nas classes filhas, esses métodos seriam opcionais.
<?php
class form_base {
protected function save() {
// antes de salvar executa metodo para avaliacao
if ($this->before_save()) {
// executa o salvamento
echo 'registro salvo com sucesso! <br>';
// depois de salvar executa metodo com rotinas após salvamento
$this->after_sabe();
} else {
echo 'seu registro nao pode ser salvo! <br>';
}
}
protected function before_save() { return true; }
protected function after_save() { }
}
class clientes extends form_base {
}
class produtos extends form_base {
protected function before_save() {
if ('blabla'=='blabla') {
return true;
} else {
return false;
}
}
}
class servicos extends form_base {
protected function after_save() {
echo 'enviando email de confirmacao! <br>';
}
}
$form_clientes = new clientes();
$form_produtos = new produtos();
$form_servicos = new servicos();
$form_clientes->save();
$form_produtos->save();
$form_servicos->save();
?>
Pelo que vejo, você está confundindo muita coisa conceitual em OO.
Vejamos, a classe pai conhece todos os métodos das classes filhas?
A resposta é, não. Logo, você não pode executar um método da classe filha a partir de uma instância de objeto da classe pai.
Então, como faz?
A segunda pergunta é, existe herança em PHP? Se existe, quando eu tenho uma instância de uma classe filha, ela pode acessar os métodos não privados da classe pai?
A resposta é sim e sim. Desde que você instancie:
ClasseFilha cf = new ClasseFilha();
Você terá acesso aos métodos inerentes à ClasseFilha e aos métodos acessíveis da classe pai, no objeto cf.
Recomendo fortemente estudar os conceitos de OO e como o PHP os aplica, para tentar seguir em frente com o que quer fazer.
Neste caso eu usaria polimorfismo.
obrigado pela resposta drsmachado.
veja bem eu nao quero executar os métodos na classe filha como uma regra… não quero usar abstração e tbem nao quero usar a implementacao de uma interface… pq desta forma eu teria q obrigatoriamente ter os métodos na classe filha.
esses metodos devem ser ser opcionais. digamos… antes de salvar a classe pai iria executar um metodo before_save, se existir na classe filha executa, se nao executa uma classe dela mesmo, vazia…
consegui implementar a classe que eu queria meio na ganbiarra: estudei no PHP uma função base chamada debug_backtrace, ela retorna um array com objetos com informacoes a ordem reversa de instanciacao até a classe atual, criei um metodo que retorna o nome da classe filha e então sabendo o nome da mesma avalio se existe nela ou nao o metodo, se tiver executa se nao tiver nao faz nada. ficou assim:
<?php
class form_base {
protected function save() {
$save = true;
// verifica se existe o metodo before_save na classe filha, before_save retorna um booleano
if (method_exists($this->trace_class(), 'before_save')) {
$save = $this->before_save();
}
if ($save) {
// executa o salvamento
echo 'registro salvo com sucesso! <br>';
// depois de salvar verifica se existe metodo com rotinas após salvamento
if (method_exists($this->trace_class(), 'after_save')) {
$this->after_save();
}
} else {
echo 'seu registro nao pode ser salvo! <br>';
}
}
// devolve o nome da classe filha
private function trace_class() {
$backtrace = debug_backtrace();
return get_class($backtrace[0]['object']);
}
}
class clientes extends form_base {
}
class produtos extends form_base {
protected function before_save() {
echo 'avaliando se pode salvar! <br>';
if ('blabla'=='blabla') {
return true;
} else {
return false;
}
}
}
class servicos extends form_base {
protected function after_save() {
echo 'enviando email de confirmacao! <br>';
}
}
$form_clientes = new clientes();
$form_produtos = new produtos();
$form_servicos = new servicos();
$form_clientes->save();
$form_produtos->save();
$form_servicos->save();
?>
se alguem souber de uma forma mais elegante de implementar isso eu agradeço… desde já saliento que a questão da pergunta é “ha como fazer” e nao “se é correto ou nao fazer”. obrigado
Cara, continuo na mesma linha de raciocínio.
Se você tem
public class Pai{
public function funcao(){
}
}
//
class Filha extends Pai{
public function funcao2(){
}
}
Se você invocar
Filha $f = new Filha();
$f->funcao();
Vai funcionar normalmente.
Não entendi o que você quis dizer ao comentar que “será executada na classe pai”.