Agora que sabemos como estender classes, vamos brincar com essa funcionalidade para aprendermos
mais sobre extensão, herança e visibilidade.
Sabemos que na nossa classe-pai (MensagemSimples), temos o método pública printTitulo(). O que
aconteceria se definíssemos um método com o mesmo nome na classe-filha (MensagemBonita)?
Vejamos:
public function printTitulo($titulo,$texto){
$mensagem = '<h1 style="color: '.$this->cor.'">'.$titulo.'</h1><p>'.$texto.'</p>';
echo $mensagem;
}
Trocando o nome do método imprime() por printTitulo(), deveríamos executá-lo assim:
$msg->printTitulo('Título da mensagem','Texto da mensagem.');
Teríamos o resultado:
Título da mensagem (em vermelho e maior a fonte)
Texto da mensagem.
Ou seja, se declararmos um método na classe-filha com o mesmo nome de outro método da classe-pai, o método da classe-filha será sempre chamada em vez do método da classe-pai.
Para utilizarmos o método da classe-pai, devemos utilizar "parent::".
Por exemplo, alterando o método imprime():
public function imprime($titulo,$texto){
parent::printTitulo('Título da classe-pai');
}
Teríamos o seguinte resultado impresso no navegador:
Título da classe-pai
Ou seja, o método imprime() chamou o método printTitulo() da classe-pai.
O mesmo raciocínio é válido para propriedades, ou seja, declarando na classe-filha uma propriedade com mesmo nome da classe-pai, ocorrerá a substituição da propriedade pai pela propriedade filha.
Agora vamos aprender um pouco sobre a visibilidade private.
Para isso vamos alterar o método imprime():
public function imprime($titulo,$texto){
$mensagem = '<h1 style="color: '.$this->cor.'">'.parent::printTitulo($titulo).'</h1><p>'.parent::printTexto($texto).'</p>';
echo $mensagem;
}
Também precisamos trocar os echo por return dos métodos printTitulo() e printTexto() da classe MensagemSimples.
Executando o nosso código, teremos no navegador:
Título da mensagem (em vermelho e maior).
Texto da mensagem.
O que aconteceu aqui foi que o método imprime() chamou (call) os métodos printTitulo() e printTexto() e apresentou o resultado na tela.
Mas o que aconteceria se colocássemos os métodos printTitulo() e printTexto como protected e private (lembre-se que eles são públicos)?
Primeiro como protected:
protected function printTitulo($valor){
$this->setTitulo($valor);
return $this->titulo;
}
protected function printTexto($valor){
$this->setTexto($valor);
return $this->texto;
}
O resultado será:
Título da mensagem (em vermelho e maior).
Texto da mensagem.
Ou seja, tudo ocorreu como o previsto pois a visibilidade dos métodos é protected, ou seja, somente podem ser executados a partir da classe que define o método (MensagemSimples) ou das classes que herdam o método (MensagemBonita).
Mas ao alterarmos de protected para private:
private function printTitulo($valor){
$this->setTitulo($valor);
return $this->titulo;
}
private function printTexto($valor){
$this->setTexto($valor);
return $this->texto;
}
Receberemos no navegador:
Fatal error: Call to private method MensagemSimples::printtitulo() from context 'MensagemBonita' in
F:\xampplite\htdocs\tutoriais\tutorial.php-oo.visibilidade-heranca-estensao.php on line 41
Isto significa que os métodos private somente podem ser executados através da classe que os define
(MensagemSimples), ou seja, não são herdados.
O mesmo vale para as propriedades.
Resumindo:
Ao estendermos uma classe, a classe que a estende (classe-filha) herda as propriedades e métodos da classe que estende (classe-pai), ou seja, os métodos e propriedades da classe-pai passam a fazer parte da classe-filha, como se nela fossem definidos.
Exceção para as propriedades e métodos private, que não são herdados, podendo somente serem chamados (call) pela classe que os define, a classe-pai.