PHP5 Orientado a Objetos: Visibilidade, herança e extensões de classes

Este artigo tratará sobre visibilidade, herança e extensão de classes (PHP Orientado a Objetos) com uma linguagem simples e de fácil entendimento, voltada principalmente para aqueles que desejam iniciar sua aventura no PHP-OO.

[ Hits: 33.574 ]

Por: EVERTON DA ROSA em 08/06/2009 | Blog: http://everton3x.github.io


Conhecendo mais a extensão de classes



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.

Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. Começando a entender visibilidade
   3. Primeiros passos na visibilidade de métodos
   4. Estendendo classes
   5. Conhecendo mais a extensão de classes
   6. Resumo e conclusão
Outros artigos deste autor

Considerações sobre as distribuições

Funções da categoria Miscelânea do PHP

Relatórios com PHP e XSLT - Conceitos iniciais e utilização básica

PHP Orientado a Objetos: Para quem está começando

SLiM: Simple Login Manager - Mini review

Leitura recomendada

Trabalhando conteúdo dinâmico com Smarty

Usando Blocos Dinâmicos com a Classe FastTemplate (Parte 1)

Administrando usuários no GNU/Linux e Samba via web com PHP

Utilizando PEAR

Organizando projetos com a classe FastTemplate (parte 2)

  
Comentários
[1] Comentário enviado por removido em 08/06/2009 - 15:44h

Muito bom o artigo Everton, está de parabéns!

[2] Comentário enviado por will fernando em 11/07/2009 - 09:16h

Muito bom ! Parabéns !

[3] Comentário enviado por wm em 16/07/2009 - 07:16h

excelente artigo

[4] Comentário enviado por henbran em 26/05/2010 - 08:53h

Bom Dia.
ESTOU COM UMA DÚVIDA EM HERANÇA EXTENDS

tenho 1 classe:
___________________________________
class A{
public function funcaoA(){
//detalhes
}
}
ººººººººººººººººººººººººººººººººººººººººººººººººººººººººººººººººº

Então tenho outra classe:
___________________________________
class B extends A{
public function funcaoA(){
//detalhes
}
}
¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
Quando tento instanciar a classe B, sendo estendida da classe A, não instancia.
ex. $instanciaB = new B(); // não funciona.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Se tiro o extends A da declaração da classe B (ficando assim: class B{ ... }), então instancia.
................................................................................................................
Já cheguei a testar todas as classes vazias, tentando saber se haveria algo de errado com as functions, porém mesmo assim continua no mesmo problema.
*******************************************************************************************
POR FAVOR, COMO EU DEVERIA FAZER ENTÃO???

[5] Comentário enviado por concurso em 08/10/2012 - 13:29h

Incrível o conteúdo, bem elaborado e explicado!

Estou iniciando na prática em php, espero que dê tudo certo.rs

Tem mais conteúdo de php elaborado por ti?

[6] Comentário enviado por everton3x em 18/10/2012 - 08:40h

Obrigado pelo comentário concurso.
Tem mais material sim. É só procurar na lista de artigos do meu perfil http://www.vivaolinux.com.br/perfil/verPerfil.php?login=everton3x


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts