2006-09-17 05:34:55
tags: 

O Zen e a arte cavalheiresca da programa

(Para ver todas as partes desta série clique aqui)

Olá, pessoal, já estamos aqui de volta para falar mais um pouquinho sobre OOP, PHP, e outras siglas igualmente ininteligíveis. Hoje quero falar sobre um tema que sempre gera muita confusão: interfaces. E, é claro, não podemos falar de interface sem olhar a etimologia dessa palavra.

O prefixo inter- vem da preposição latina inter, que significa "entre, no meio de". A palavra face, também de origem latina (fascia), significa "camada externa". Juntando as duas coisas, temos um termo genérico que significa praticamente qualquer coisa em tecnologia. Temos interfaces gráficas, interfaces com o usuário, interfaces RS232, interfaces usb, e por aí vai.

O conceito denominado de interface em OOP é bastante diferente disso tudo. No nosso mundo imaginário de carros, superpoderes, gnomos e outras criaturas fantásticas orientadas a objeto, interfaces são simplesmente definições padronizadas de acesso a funções que estão dentro das classes que as implementam. Falando assim parece bem complicado, mas não é não. Na verdade, na verdade, se a gente olhar com muito cuidado, nós de fato já usamos o conceito de interface aqui mesmo nos artigos anteriores.

Explico: quando nós criamos uma classe, estamos criando também uma interface. Lembra que nós construímos dois carros, um FiatUno e uma FerrariF1, e ambos podiam ->acelerar() ? Justamente! Ajoelhe-se diante do poder das interfaces!

Ao estender a classe Automovel para criar a classe FiatUno e a classe FerrariF1 nós estamos automaticamente implementando a interface usada na classe automóvel nas duas. Assim, temos absoluta certeza que todas as classes-filhas da classe Automovel vão poder ->acelerar(). Esse é exatamente o conceito de interface: a padronização do acesso aos dados e funções de uma classe ou objeto.

Mas o que é realmente interessante é que algum desses gênios malucos que inventaram os conceitos de OOP acordou um belo dia e teve uma idéia brilhante: "Perai, mas eu não preciso ter que criar classes-filhas toda hora pra usar uma interface!". Nasciam as palavras-chave interface e implements, que permitem a criação de interfaces que podem ser usadas entre classes que não tem nenhum parentesco entre si.

E eu estou aqui para provar tudo isso implementando Superpoderes em Automóveis! Você há de concordar que um Automovel não tem nada a ver com um SerHumano, já que eles não têm nenhum parentesco. Como ter certeza que essas classes e todos os seus filhos possam usar objetos da classe SuperPoder de forma padronizada? É fácil:

Primeiro, criamos a interface SuperHeroi:

 interface SuperHeroi {
    public function ativar(SuperPoder $superpoder);
} 

Bom, como você pode notar, a função ativar só vai funcionar se você mandar pra ela o SuperPoder desejado durante a chamada da função. Se mandar texto, número ou qualquer outra coisa vai ganhar um erro de presente.

Agora vamos alterar nossas classes Automovel e SerHumano para implementar a interface SuperHeroi:

Class SerHumano implements SuperHeroi { 	
    public $nome;
    public $vivo; 	
    public function __construct($nome) {
        $this->nome = $nome;
        $this->vivo = true;  	
    }
    public function taVivo() { 
        if($this->vivo == true) {             		
            print "Sim, eu estou vivo, e meu nome é $this->nome!"; 	
        } else {             	
            print "..."; 	
        }  	
    }
    public function ativar(SuperPoder $superpoder){
        $superpoder->ativar()
    }
} 

e agora a classe Automovel:

 abstract class Automovel implements SuperHeroi {
     public $aceleracao;
     public $velocidade_atual;
     public $cor;

     public function acelerar() {
        $this->velocidade_atual = $this->velocidade_atual + $this->aceleracao;
        print "Acelerando! Agora a velocidade é de " . $this->velocidade_atual . "Km/h!";
     }    
    public function ativar(SuperPoder $superpoder){
        $superpoder->ativar();
    }
 }

 

Agora, tanto os objetos SerHumano quanto objetos da classe Automovel (incluindo aqueles das classes FiatUno e FerrariF1, já que pela herança um FiatUno ou uma FerrariF1 sempre têm todas as propriedades e funções da classe Automovel) já podem ->ativar() um SuperPoder. Como a classe SuperPoder é abstrata e ninguém consegue ativar um SuperPoder abstrato, vou ativar a SuperForca:

$meucarro = new FerrariF1('vermelha'); 
$meucarro->ativar(new SuperForca);
// Meu deus, posso levantar um caminhão! 

E os gnomos, você deve estar se perguntando. Eles virão... Eles virão...

18 Comentários:

[Marco Gomes]  Acho que vc fez uma confusão aí nos códigos, vc criou uma interface interface SuperHeroi e, no automóvel, implementou SuperPoder. Quem está confuso sou eu ou você?  [LINK]

[danilo]  Fala Marco! Tem toda razão fiz uma confusão por aqui. Já corrigi, grande abraço!  [REPLY]

[João Antônio]  Essa orientação que o ZEN demonstra é muito boa!! Esse é o mesmo ZEN do CSS, porque é muito bom tb!! Abraço  [REPLY]

[Tarcísio Sassara]  Nossa, colega. Muito bom! Acredito que meu QI aumentou 15%!!  [REPLY]

[danilo]  Valeu João! Grande Abraço!  [REPLY]

[danilo]  Obrigado Tarcísio! Grande Abraço também!

[Tarcísio Sassara]  Danilo, estou prestes a adquirir um livro, você poderia indicar alguns outros livros que seja legal para quem está começando com o php? Eu tenho conhecimento de Lógica, programo em VB, mas agora estou migrando para a plataforma WEB. E escolhi o PHP pelas vantagens que ele oferece. Segue o link do livro que irei comprar.  [LINK]  [REPLY]

[danilo]  Olha Tarcisio, infelizmente acho que os melhores livros são em ingles... o melhor é o da Apress chamado PHP 5 Objects, Patterns, and Practice...

[Tarcísio Sassara]  Concordo, os melhores títulos são os escritos na língua inglesa, estou lendo também o titulo "PHP 5 and MySQL Bible", este peguei emprestado, o inglês não é um problemão, mas é muito chato, ainda por enquanto para mim, ficar lendo muitas horas me cansa. O titulo que comentei anteriormente anteriormente, é uma tradução do americano: PHP and MySQL Web Development. Agradeço pela dica, vou dar uma olhada no livro que você citou!  [REPLY]

[Giovanni]  eu queria um convite pro Wasabi, leio há tempos sobre ele, mas nao consegui um convite... agradeço a atenção ! bom final de semana !  [REPLY]

[danilo]  Já te mando, Giovanni! Grande Abraço.  [REPLY]

[André Valongueiro]  Q blza garotão! Uma das séries de artigos mais legais que já li na blogosfera. Clareou a vida! Cheguei atrasado mas estou em dia com as leituras, aguardando o próximo artigo. Meus parabéns veinho! Abração.  [REPLY]

[Leandro]  Tá muito bom seus posts sobre OO. Estou aguardando a aparição dos gnomos.  [REPLY]

[Danilo]  Oi Junio, veja a parte 4, as definições das classes FerrariF1 e FiatUno estão lá, precisa digitar tudo, ok? Abraço grande!  [LINK]  [REPLY]

[Junio]  Olá Danilo Medeiros estou estudando PHP, tendo você como professor, escrevi todas estas linhas de códigos e quando vou executar aparece: "Fatal error: Class 'FerrariF1' not found ".Agradeço desde já.  [REPLY]

[Junio]  Danilo Medeiros, irei criar três arquivos ".php", automovel, serhumano e interface ?  [REPLY]

[danilo]  Voce pode colocar cada classe em um arquivo, sim, Junio, mas vai ter que fazer um include no seu arquivo principal para que eles sejam lidos, ok?  [REPLY]

[Junio]  Muito obrigado pela atenção Danilo, desejo paz e saude para ti.  [REPLY]