Orientação a Objetos – parte 2
Salve
Na parte 1 falamos sobre o café com leite da Orientação a Objetos no PHP: classes, objetos, atributos e métodos. Desta vez vamos nos aprofundar mais no assunto e falar sobre herança, visibilidade e polimorfismo.
Utilizamos a herança para especializar uma determinada classe. No artigo anterior citamos os cães… imaginemos aqueles cães como cães comuns, mas precisamos descrever outro tipo: os cães de guarda, que possuem habilidades que o Max ou o Tirolez não possuem; com OO não precisamos escrever uma classe nova só para o Rush, o pastor alemão do vizinho. Extendemos a classe Cachorro original, herdando suas propriedades e métodos, e alterando o que for conveniente para a nova classe. Por exemplo: podemos dizer que o Rush, ao rosnar induza o cachorro para o qual ele faça de alvo a sentir medo, além de atribuir-lhe um novo método: morder (que originalmente, Max e Tirolez não são capazes de realizar).
Basicamente, para conseguirmos o que descrevi acima, precisamos de extender a classe Cachorro original:
class Cachorro{
//conteudo original
}
class CaoDeGuarda extends Cachorro{
function rosnar($outroCachorro){ /*novo conteúdo deste método*/}
function morder($alvo){ /*conteúdo deste método*/}
}
Para que isso funcione, precisamos conhecer alguns conceitos de OOP: visibilidade e polimorfismo
Visibilidade, que citei na primeira parte, é a declaração de como serão usadas (visíveis) os atributos / métodos de uma classe; os tipos de visibilidade são private, public e protected. Private define que a entidade somente estará acessível em métodos da classe em que a mesma foi declarada. Public define que a entidade pode ser acessada tanto por métodos internos, como por processos externos. Protected é como a private, porém permite que classes filhas acessem a entidade diretamente, sem sobrescrevê-la, e sem permitir o acesso a chamadas externas ao âmbito da classe/objeto.
Geralmente não usamos muito o protected; usamos na maioria das vezes o private para os atributos e o public para os métodos, quando estamos apenas descrevendo dados.Fazemos isso para que sempre seja necessária a execução de um método para alterar o valor de um atributo, podendo assim validar o novo valor, por exemplo. No PHP5, se não definirmos a visibilidade dos métodos, eles assumem como public, assim como se declararmos os atributos com var (PHP4), para manter a compatibilidade.
Polimorfismo: conceito pelo qual entende-se que uma classe filha (extendida), pode conter um mesmo método que a classe ancestral, embora sua execução seja diferente da original, reescrevendo o método da classe pai, utilizando a mesma assinatura; esta por sua vez é a maneira como é declarado o método, sua visibilidade, número e tipo de parâmetros e tipo de retorno; como o PHP não é tipado, ou seja, não atribuímos o tipo das variáveis, podemos nos referenciar a assinatura como visibilidade e número de parâmetros de um dado método.
Para entendermos esses conceitos, ai vai um exemplo:
class A{
private $a1 = '1';
public $a2 = '2';
protected $a3 = '3';
public function mostrar(){
echo 'Classe A:[';
echo $this->a1;
echo $this->a2;
echo $this->a3;
echo ']<br />';
}
}
class B extends A{
public function mostrar(){
//aqui estamos utilizando o polimorfismo para reescrever o método mostrar()
echo 'Classe B:[';
echo $this->a2;
echo $this->a3;
echo $this->a1;
echo ']<br />';
}
}
$a = new A;
$b = new B;
@$a->mostrar();//mostra Classe A:[123]
@$b->mostrar();//mostra Classe B:[23]
echo $a->a2;//mostra 2
echo $a->a3;//erro
echo $a->a1;//o script nao chega aqui
Esse exemplo nos dá uma idéia do que acontece às propriedades com suas visibilidades definidas.
Voltando aos nossos cães, podemos dizer que a classe CaoDeGuarda é mais específica que Cachorro, sua classe-pai ou superclasse. Podem perguntar ‘Certo, mas o que a tal da visibilidade tem a ver com os cachorros?’; digo que se na parte 1 declarássemos os métodos com as visibilidades específicas, teríamos que mudar muita coisa naquele codigo, e neste, para que tudo ocorresse bem. E mais: do jeito que está agora, podemos alterar o nome do ‘Tirolez’ para ‘123testando’ a qualquer momento.
Vamos alterar as classes para ficarem mais adequadas:
class Cachorro{
private $nome;
private $raca;
private $cor;
private $peso;
private $saude;
public function __construct($n,$r,$c,$p,$s=100){
$this->nome = $n;
$this->raca = $r;
$this->cor = $c;
$this->peso = (float)$p;
$this->saude = (int)$s;
public function latir(){ /*código que fará o cachorro latir*/ }
public function rosnar($outroCachorro){ /*código que fará o cachorro rosnar para outro */ }
public function mijar($onde){ /*código que fará o cachorro urinar em algum lugar */ }
public function dormir(){ /*código que fará o cachorro dormir e recuperar saúde*/ }
public function setSaude($novaSaude){
$this->saude = (int)($novaSaude > 100) ? 100 :$novaSaude;
}
public function getSaude(){
return $this->saude;
}
}
class CaoDeGuarda extends Cachorro{
function rosnar($outroCachorro){ /*O CaoDeGuarda faz o outroCachorro amedrontar-se*/ }
function morder($alvo){
$saudeOriginal = $alvo->getSaude();
$saudeDepoisDaMordida = $saudeOriginal*0.9;//o alvo perde 10% da saúde a cada mordida
$alvo->setSaude($saudeDepoisDaMordida);
}
}
Bom, podemos fazer a mesma brincadeira da parte 1:
$rush = new CaoDeGuarda('Rush','Pastor','Preto/Bege',50);
$ralf = new Cachorro('Ralf','Fox Paulistinha','Preto/Branco',12);
$ralf->rosnar($rush);//ralf, com seus 30 cm de bravura e estupidez...
$rush->rosnar($ralf);//agora ele viu o tamanho da encrenca;
while($ralf->getSaude() > 50){
$rush->morder($ralf);
}
//sim, gastamos uma boa grana com o veterinário
Assim encerramos esta parte. Na próxima falarei sobre abstração, métodos estáticos, interfaces e mais. Até lá
3 comentários até agora
Leave a reply

Ae Draco, tá muito bom
parabéns.
Gostei da forma como vc apresenta este assunto. Como vc mesmo disse no início, encontramos milhares de sites sobre esse material, no entanto, colocam de uma maneira tão abstrata que fica difícil pra quem está começando. Parabéns.
Boa iniciativa… Vlw