Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Da última vez, falamos sobre visibilidade e sobre como conseguimos ocultar informações utilizando os modificadores de visibilidade private e protected e assim, encapsular a lógica por trás de uma operação, falamos também que utilizamos a visibilidade public para os métodos que desejamos permitir que sejam acessados em nossos objetos e que esses métodos públicos chamam-se, na verdade, métodos de interface.
Quando eu disse que o encapsulamento era um dos aspectos mais importante era porque a interface de um objeto é definitivamente o aspecto mais importante em orientação a objetos.
Mas, se interface é o aspecto mais importante, precisamos definir interface, então, o que é interface ?
(computer science) a program that controls a display for the user (usually on a computer monitor) and that allows the user to interact with the system
Tradução livre:
(ciências da computação) um programa que controla uma exibição para o usuário (normalmente em um monitor) e que permite que o usuário interaja com o sistema
Perceba duas palavras chaves na tradução:
1. exibição /applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/seta.gif&key=e2d72b30771339c36df1f88688ecc571784dab60a19e2c7c2ff398c277802ac0" alt="Imagem Postada" class="bbc_emoticon"> o que podemos ver
2. interaja /applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/seta.gif&key=e2d72b30771339c36df1f88688ecc571784dab60a19e2c7c2ff398c277802ac0" alt="Imagem Postada" class="bbc_emoticon"> o que podemos trabalhar com
Então, interface é aquilo que podemos ver e trabalhar com, em orientação a objetos é exatamente a mesma coisa, métodos de interface são os métodos que podemos ver e trabalhar com, ou seja, por definição todo método público é um método de interface.
O fato, senhores, é que nossos objetos não saberiam como trabalhar uns com os outros se não fossem os métodos de interface. Até agora, falamos apenas como construir um objeto e como esconder sua lógica, porém, agora passaremos, enfim, a falar sobre programação orientada a objetos.
Já sabemos que herança de classe serve para compartilhar código entre seus herdeiros, agora passaremos a falar sobre tipos de objetos, vejam só:
"Atirei o pau no gato-to, mais o gato-to não moreu-reu-reu....."
Um pouco de português:
Atirei /applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/seta.gif&key=e2d72b30771339c36df1f88688ecc571784dab60a19e2c7c2ff398c277802ac0" alt="Imagem Postada" class="bbc_emoticon"> verbo bi-transitivo, quem atira atira alguma coisa em alguém. /applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/seta.gif&key=e2d72b30771339c36df1f88688ecc571784dab60a19e2c7c2ff398c277802ac0" alt="Imagem Postada" class="bbc_emoticon"> No caso, o sujeito oculto sou eu, eu atirei o pau no gao.
pau /applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/seta.gif&key=e2d72b30771339c36df1f88688ecc571784dab60a19e2c7c2ff398c277802ac0" alt="Imagem Postada" class="bbc_emoticon"> substantivo, objeto direto pedido pelo verbo.
gato /applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/seta.gif&key=e2d72b30771339c36df1f88688ecc571784dab60a19e2c7c2ff398c277802ac0" alt="Imagem Postada" class="bbc_emoticon"> substantivo, objeto indireto, pedido pelo verbo.
Ok, hehehehe, temos 3 participantes: o pau, o gato e eu
class Pau {
}
class Gato {
public function acerta( Pau $pau ) {
echo 'Miiiaaaaaauuuuuuuuuuuuu !!!!!';
}
}
class Eu {
public function atira( Pau $pau , Gato $gato ) {
$gato->acerta( $pau );
}
}
$gato = new Gato();
$pau = new Pau();
$eu = new Eu();
$eu->atira( $pau , $gato );
A saída será:
Miiiaaaaaauuuuuuuuuuuuu !!!!!
Atenção sociedade protetora dos animais, eu não faço esse tipo de coisa, foi meramente ilustrativo.
Bom, se os senhores prestarem atenção nas classes Eu e Gato, perceberão que existem um método atira() que recebe dois parâmetros, um Pau e o Gato. Percebam que essa implementação é muito dura e não conseguimos reproduzir a parte gramatical da coisa: "Quem atira, atira alguma coisa em alguém", porque Eu atira só e somente só um Pau no Gato, se precisarmos atirar Pedras ou qualquer outro tipo de objeto em Cães, Pássaros, ou qualquer outra coisa não será possível.
Para que consigamos atirar qualquer coisa em qualquer outra coisa, precisamos focar nos métodos de interface apenas, vejamos:
O gato possui um método de interface chamado acerta(), se transformarmos esse método em um contrato, onde qualquer classe que assine esse contrato precise necessariamente tê-lo, conseguiremos jogar alguma coisa em qualquer coisa que possua esse método:
interface Alvo {
public function acerta( Pau $pau );
}
Ai está, como podem ver, a construção de linguagem interface não implementa nada, ela é só um contrato que estipula um conjunto de operações que nossos objetos deverão ter, operações as quais nossos objetos poderão ver e trabalhar com.
Com a interface Alvo, podemos jogar Paus em gatos, cachorros, pessoas, paredes, enfim, qualquer coisa pode ser um alvo:
class Gato implements Alvo {
public function acerta( Pau $pau ) {
echo 'Miiiaaaaaauuuuuuuuuuuuu !!!!!';
}
}
class Cao implements Alvo {
public function acerta( Pau $pau ) {
echo 'Aaaaauuuuuuuuuuu !!!!!';
}
}
class Parede implements Alvo {
public function acerta( Pau $pau ) {
echo 'plof !!!!!';
}
}
Mas, ainda temos um problema com nossa questão gramatical, só conseguimos jogar Paus, e se quisermos jogar pedras ????
Você pode estar pensando: "Mas o Pau não tem métodos de interface"
O fato, é que não precisamos necessariamente de um método de interface para definir o Tipo de um objeto:
interface Projetil {
}
E dessa forma:
class Pau implements Projetil {
}
class Pedra implements Projetil {
}
class Sapato implements Projetil {
}
E agora nosso Alvo ficaria assim:
interface Alvo {
public function acerta( Projetil $projetil );
}
E nossas implementações:
class Gato implements Alvo {
public function acerta( Projetil $projetil ) {
echo 'Miiiaaaaaauuuuuuuuuuuuu !!!!!';
}
}
class Cao implements Alvo {
public function acerta( Projetil $projetil ) {
echo 'Aaaaauuuuuuuuuuu !!!!!';
}
}
class Parede implements Alvo {
public function acerta( Projetil $projetil ) {
echo 'plof !!!!!';
}
}
Agora, podemos jogar várias coisas em várias outras coisas:
$gato = new Gato();
$cao = new Cao();
$parede = new Parede();
$pau = new Pau();
$pedra = new Pedra();
$sapato = new Sapato();
$eu = new Eu();
$eu->atira( $pau , $gato );
$eu->atira( $sapato , $cao );
$eu->atira( $pedra , $parede );
A saída:
Miiiaaaaaauuuuuuuuuuuuu !!!!!Aaaaauuuuuuuuuuu !!!!! plof !!!!!
Bom, como o assunto é muito extenso e ainda falta muito, vamos parar por aqui hoje. No próximo artigo da série PHP Orientado a Objetos continuaremos falando sobre métodos de interface e polimorfismo.
/applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/wink.gif&key=0566fd943552bcff9cb1b879403ca34b5ff8f67befaac7fe4648006e9f764689" alt="Imagem Postada" class="bbc_emoticon">
Índice /applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/seta.gif&key=e2d72b30771339c36df1f88688ecc571784dab60a19e2c7c2ff398c277802ac0" alt="Imagem Postada" class="bbc_emoticon">
>
Elas não servem para "amarrar" teu código, te obrigando a adicionar métodos e sim flexibilizar, alterando os comportamentos.
Belíssima colocação, Bruno.
Apesar de serem conhecidas como "contratos" as interfaces servem justamente para "desamarrar" seu código, quando, em vez de manipular seu objetos em termos de implementações você passa a manipulá-los em termos de interfaces você faz com que seus objetos deixem de conhecer uma implementação específica, isso reduz o custo de implementação já que causará de imediato a redução das dependências.
Mais a frente, falaremos sobre polimorfismo e ilustraremos como manter os participantes sem conhecimento de uma implementação pode ser altamente favorável para a modelagem de uma aplicação e objetos reutilizáveis.
>
Mas cachorro quando a apanha faz "Caim, caim, caim..."
hehehehe, novamente, uma boa colocação, farei um "bug fix" no código de exemplo para resolver a situação.
João, a tua didática é simplesmente excepcional! Meus parabéns. Estudo de Orientação a Objetos de primeiríssima qualidade e facilidade de abstração.
Se eu tivesse começado com um professor assim, certamente não estaria dando tanta cabeçada hoje.
>
João, a tua didática é simplesmente excepcional! Meus parabéns. Estudo de Orientação a Objetos de primeiríssima qualidade e facilidade de abstração.
Se eu tivesse começado com um professor assim, certamente não estaria dando tanta cabeçada hoje.
[2] :(
:D
tenho uma dúvida se eu nao usa-se o implements ali, e apenas class não iria dar o mesmo resultado?
digo o que está sendo feito é apenas repetir o mesmo código 3 vezes não? o código inicial.
Não entendi a vantagem.
BTG, é assim que a interface trabalha. Note que os "alvos" não esperam uma classe específica, esperam algo que se comporte da maneira que eles precisam.
sem os implements, teríamos algo assim:
class pau {}
class pedra {}
class sapato {}
class gato {
public function acerta($item){
if(
$item instanceof pau ||
$item instanceof pedra ||
$item instanceof sapato
) echo "MIAU!!";
}
}
class cachorro {
public function acerta($item){
if(
$item instanceof pau ||
$item instanceof pedra ||
$item instanceof sapato
) echo "Caim, caim!!";
}
}
class parede{
public function acerta($item){
if(
$item instanceof pau ||
$item instanceof pedra ||
$item instanceof sapato
) echo "Ploft!!";
}
}
Perceba que o efeito foi o contrário do esperado, ao invés de escrever menos, escrevemos MAIS, isso porque temos que prever em cada classe-alvo, TODOS os tipos de objetos que podem ser atirados nelas.
Ainda existe outro ponto: Ali podemos atirar:
Pau
Pedra
Sapato
E temos três classes que podem se comportar como alvos:
Gato
Cachorro
Parede
Perceba que se eu quiser trabalhar com um novo objeto, um tijolo e também adicionar um novo possível alvo, uma janela, eu teria:
Modificar a estrutura dos já prontos gato, cachorro e parede para adicionar a nova possibilidade de projétil, o tijolo.
Eu teria que criar uma nova classe 'janela' também implementando a função dessa maneira, prevendo todo tipo de objeto que pode ser arremessado contra ela.
Seguindo o modelo passado pelo João, veja como é simples a criação de um novo projétil e um novo alvo:
class Tijolo implements Projetil { }
class Janela implements Alvo {
public function acerta(Projetil $projetil) {
echo "Algo foi arremessado pela janela.";
}
}
Perceba que nem sequer tocamos nas implementações já existentes (gato, cachorro, parede, pau, pedra, sapato), mas é possível arremessar um tijolo tanto na janela, quanto no gato, no cachorro ou na parede.
Também tornou-se possível arremessar paus, pedras e sapatos pela janela.
No segundo item deste capítulo, é abordada mais a fundo a característica de polimorfismo, que permite que um objeto se comporte da maneira que precisamos que ele se comporte.
Veja que cenário interessante podemos criar:
class Gato implements Alvo, Projetil { }
Agora tornou-se possível arremessar o gato pela janela, com uma mudança MÍNIMA de código.
otima explicacao evandro =]
Note que os "alvos" não esperam uma classe específica, esperam algo que se comporte da maneira que eles precisam
.
valww
>
Veja que cenário interessante podemos criar:
class Gato implements Alvo, Projetil { }
Agora tornou-se possível arremessar o gato pela janela, com uma mudança MÍNIMA de código.
kkkk,
Fiquei me imaginando, jogando um gato em um cachorro !!!
Muito bom Evandro !!!
http://forum.imasters.com.br/public/style_emoticons/default/clap.gif
Saquei, muito obrigado agora entendi a idéia disso. Muito obrigado mesmo = )
Boa noite galera !!!
Estou estudando Orientado Objeto e nunca tinha lido um tutorial tão bom como esse. Parabens João Batista.
Mas estou com uma dúvida.
Para mim deu um erro e lendo e relendo o tuto cheguei em uma conclusão.
Para toda ação de jogar algo em alguma coisa teria que criar uma uma class nova e depois o instaciar o objeto. É Isso mesmo???
Não é necessário o código abaixo???
Dessa forma deu certo e deus os prins certinhos.
Abraços !!!
class Eu {
public function atira( Pau $pau , Gato $gato ) {
$gato->acerta($pau);
}
}
class EuCao {
public function atira( Sapato $sapato , Cao $cao ) {
$cao->acerta($sapato);
}
}
class EuParede {
public function atira( Pedra $pedra , Parede $parede ) {
$parede->acerta($pedra);
}
}
$eu = new Eu();
$eucao = new EuCao();
$euparede = new EuParede();
$eu->atira( $pau , $gato );
$eucao->atira( $sapato , $cao );
$euparede->atira( $pedra , $parede );
Eu tinha tentado assim mas não tinha funcionado.
class Eu {
public function atira( Pau $pau , Gato $gato ) {
$gato->acerta($pau);
$cao->acerta($sapato);
$parede->acerta($pedra);
}
}Deu certo porque você limitou o type hinting dos Projéteis a Paus, Sapatos e Pedras e os Alvos a Gatos, Cães e Paredes.
O foco do artigo é o polimorfismo proporcionado pelas interfaces.
Releia o artigo e verá que em dado momento aperece nas classes de Projétil um implements para a interface Projetil e nas de Alvos um para interface Alvo o que significa que no type hinting da classe Eu os parâmetros podem ser qualquer coisa que implementem essas interfaces.
Tudo o que existe pertence a um "grupo":
Nota: Em negrito, as interfaces
Perceba que com isso você pode implementar na classe Eu um método dirigir que espere como argumento o objeto de um veículo.
Você não precisará apontar o type hinting para Carro, Moto ou Caminhão e sim para Veículo.
Dessa forma interpretador ficará responsável por verificar se o objeto passado ou é uma instância da classe Veículo, no caso rudimentar de haver um único meio de transporte genérico ou se implementa a interface Veículo, que pode ser qualquer uma das classes citadas, desde que implementem a interface especificada.
;)
Obrigado Imaggens !!!
Gente se tiver falando besteira porfavor me avisem !!!!
Entendi em partes o que você disse, mas não sei o que é type hinting. Mas tudo bem.
Eu entendi também que para cada ação minha preciso de uma interface que seja generica e atenda a todo tipo de ação.
interface Projetil {
}
O que eu não entendi realmente é para que eu vou implementar a minha class Pau a Projetil se que projetil não tem nada.
class Pau implements Projetil {
}
class Pedra implements Projetil {
}
class Sapato implements Projetil {
}
O que isso vai fazer??? O que ele recebe? E para quem ele vai devolver o objeto?
E mais uma duvida.
A minha class Eu está assim.
class Eu {
public function atira( Projetil $projetil , Gato $gato ) {
$gato->acerta($projetil);
}
}
O X da questão é:
1- Quando eu faço isso:
$eu = new Eu(); O que realmente acontece? Imagino eu que tenho lá dentro o um monte de números de memória.
2- Na class Eu Chamo o metodo acerta() passado um projetil. Que é do tipo gato e que tem lá dentro o Miaaauuuuuuu.
class Eu {
public function atira( Projetil $projetil , Gato $gato) {
$gato->acerta($projetil);
}
}
Até ai tudo bem consegui trazer o Miiiaaauuuu.
Mas quando vou fazer para Cao da errado?
Para mim se a interface é generica tenho o Metodo Cao que passa o Auuuuuuuuuuuu, e instancio ele com o new porque quando vou colocar na class Eu
o metodo de interface (que é o mesmo nome para todos acerta) esta dando erro?
Já fiz um monte de coisa mas da errado uma deles é essa.
class Eu {
public function atira( Projetil $projetil , Gato $gato, Cao $cao) {
$gato->acerta($projetil);
$cao->acerta($projetil);
}
}
Mas da erro de eu estar passando dois parametros ao inves de um.
Sei que isso já foge do assunto de Polimorfismo, mas acho que essa á a principal dúvida de quem está começando a programar em O.O.
Não quero código, quero entender isso por se não entender como funciona não vai ser um código que vai clarear a cabeça, se vocês tiverem um
tutorial onde explique isso ou se poder me dar uma força me falem, por favor.
Obrigado.
:P hehe tambem ainda so um iniciante em OOP mas vo da minha opinião
um objeto propoen resolver um problema .. entao digamos que meu problema é quero quebrar a janela..
tenho meu objeto que Quebra
ele foi construido com o objetivo de quebrar algo
meu metodo que atira
ele atira algo possivel de ser atirado em alguma coisa possivel de ser quebrada
vai ser como eu vou quebrar a janela
vou quebrar atirando uma pedra na janela
com isso meu problema é resolvido
caso tenha algo que pertença ao mesmo grupo logico coloco aqui
por exemplo nem sempre posso quebrar (que é o objetivo do meu objeto) atirando coisas
eu posso precisar dar uma maretada para quebrar :P
isso seria outro metodo de quebrar nao ? =]
valwww
Primeiro por partes - type hinting
Vamos analisar o seu código
class Eu {
public function atira( Projetil $projetil , Gato $gato) {
$gato->acerta($projetil);
}
}class Eu {
public function atira( Projetil $projetil , Alvo $alvo ) {
$alvo->acerta($projetil);
}
}interface Alvo {
public function acerta( Projetil $projetil );
}Compreendeu a idéia? Se não tiver compreendido, pode perguntar de novo.
Carlos Eduardo
Bom dia Pessoal !
Muito obrigado mesmo a todos você que estão me ajudando !!!
Matias
Cara entendi agora que a minha class Eu também tem quer genérica e que recebe qualquer coisa.
Olhando o código e chego a seguinte conclusão:
A class Eu não quer saber o que estão passando para ele, ele recebe o objeto seja qual for ele ($pau , $gato , $sapato , $cao ou $pedra , $parede) e
ele chama o metodo de interface passando esse dois parametros.
Lá na class Eu tem um Metodo acerta, passo o objeto projetil do tipo alvo e lá no metodo de interface da o print.
É isso mesmo?
Show cara acho entendi agora !!!
Mas a questão das interface projetil e as class Pau, Pedra e Sapato
Pelo que o Evandro disse economiza código e não preciso ficar verificando tudo para todos os objetos, eu crio uma interface do tipo Projetil.
Tendo esse objeto do tipo Projetil eu adiciono ele na class Pau, Pedra e Sapato usando o implements, ai essas class tem o objeto tipo Projetil implementado pela interface Projetil.
É isso mesmo? Estou certo?
E mais uma coisa...
quando faço isso:
$eu->atira( $pau , $gato );
$eu->atira( $sapato , $cao );
$eu->atira( $pedra , $parede );
Eu chamo chamo o mesmo método atira para todos e mudo os parametros eu simplemente comentei o
//$eu->atira( $pau , $gato );
E ele soube qual interface chamar certinho. Como ele sabe que é esse o cara que eu quero trazer? Se todos as class recebe projetil ?
Eu fiz uma teoria aqui:
Vamos imaginar o seguinte:
quando eu estâncio o objeto eu
$eu->atira( $sapato , $cao ); é como se foce assim
$eu->atira( $sapato , $cao );
Eu = ?
$sapato = sapato
$cao = cao
Tem como eu dar um print nesses objetos?
E com isso ele vai direto na Class Cao porque o objeto é do tipo cao.
Estou certo?
Sei que estou sendo chato gente mas porfavor me ajudem.
Abraços !!!!
Will, entenda que não há um objeto do tipo projétil interfaces em OOP descrevem comportamento. Nós passamos um objeto que se comporte como um projétil.
>
Veja que cenário interessante podemos criar:
class Gato implements Alvo, Projetil { }
Agora tornou-se possível arremessar o gato pela janela, com uma mudança MÍNIMA de código.
$gato = new Gato;
$gato, inicialmente (pelo código do João Batista) era um objeto do tipo gato que se comporta como alvo.
$gato, pela minha implementação de exemplo continua sendo um objeto do tipo gato que pode se comportar tanto como alvo quanto como projétil.
Tudo depende da função (método) que ele exercerá no sistema.
Veja:
interface MassStorage {
public function PlugarNaUSB();
public function RemoverDaUSB();
public function EnviarDados();
public function GravarDados($dados);
public function Formatar();
}
class Pendrive implements MassStorage, Projetil {
private $plugado = false;
private $data = array();
public function PlugarNaUSB(){
$this->plugado = true;
}
public function RemoverDaUSB(){
this->verificaPlugado();
$this->plugado = false;
}
public function EnviarDados(){
this->verificaPlugado();
return $this->data;
}
public function GravarDados($dados){
this->verificaPlugado();
$this->data[] = $dados;
}
public function Formatar(){
this->verificaPlugado();
$this->data = array();
}
private function verificaPlugado(){
if(!this->plugado) throw new Exception('Não estou plugado em uma porta USB!');
return true;
}
}
$pendrive = new Pendrive;
$eu->atira($pendrive, $gato);
Veja que, quando eu atiro um objeto que se comporta como Projetil todas as outras funções(métodos) que ele possa eventualmente possuir, são ignoradas, e só trabalhamos com o que precisamos, no caso as funções (nenhuma) que o Projetil implementa e as funções (acerta) que um alvo implementa.
no caso do exemplo do gato-protétil:
eu->atira($gato1,$gato2)
Não interessa o que, quais e como são implementados os métodos nos objetos, eu PRECISO de um projétil, pra jogar nalguma coisa que FAÇA ALGO quando for atingido. Este algo é definido pelo método acerta().
Chegou a ler o capítulo 1.4.2 deste tópico? Ele complementa o 1.4.1 (onde estamos). Poderá ajudar também nos esclarecimentos.
Boa noite Pessoal.
Evandro, cara muito obrigado pelas explicação !!!!
Acho que agora foi http://forum.imasters.com.br/public/style_emoticons/default/joia.gif para fixar mesmo o conceito é fazendo tudo denovo com outros exemplos.
Agradeços a todos de pela ajuda !!!!
Muito Obrigado !!! :D
Abraços !!!!
Consegui fazer tudo certinho nessa aula... ai fui mostra pra minha namorada e falei pra ela escolhe qual deles ela queria tacar e na onde kkk ela falo "Eu quero taca m***** no ventilador" huahuahuah ta ae a função:
class m***** implements Projetil{
}
class Ventilador implements Alvo {
public function acerta( Projetil $projetil) {
echo 'Écatiiiiiiiiiiiiiiiiii !!!';
}
}
$eu->atira( $m***** , $ventilador );
E sai:
Écatiiiii !!!
ela que criou tudo kkkkkkkkkkkk
Will, entenda que não há um objeto do tipo projétil interfaces em OOP descrevem comportamento. Nós passamos um objeto que se comporte como um projétil.
eu ? /applications/core/interface/imageproxy/imageproxy.php?img=http://forum.imasters.com.br/public/style_emoticons/default/mellow.gif&key=356581a1bd5b39ccefe91ac9b9df56effa5e2b9f2417c09b2bf6bec26392e3d6" alt="Imagem Postada" />
William Aquino.
João estou acompanhando seus artigos e estou achando fantastico, vou recomendar para alguns professores que eu tenho na faculdade, com uma didática muito ruim com exemplos sem nexos e quem ninguém entende nada. Bom, depois desse desabafo, gostária que você me esplicasse como você invocou os métodos atira da classe eu, pois não consegui entender sua chamada, porque na primeira implementação ela ficou restrita apenas na classe gato e quando faço a instanciação pelo menos com gato funciona, mas com as outras não, gostária se possível desse este exemplo, pois percorri as discussões e vi várias dúvidas sobre isso e desde já agradeço muito, finalmente estou entendo a importância da herança e do polimorfismo.
Parabéns João, você entende do assunto...........................
Agradeço o João pelo maravilhoso artigo, aprendendo muito com ela.
Agora vou tentar resolver sua dúvida Rogério Lopes...
No início do artigo não havia interfaces e só existia um Alvo, que era o Gato, mais abaixo foi criado a interface Alvo e implementamos ela em todas as classes alvos, inclusive Gato.
Começamos criar vário alvos e implementar a interface Alvo neles só que aí ficou um problema o método atirar ainda continua aceitando apenas Gato.
A princípio tínhamos a classe atirar dessa forma:
public function atira( Pau $pau , Gato $gato ) {
$gato->acerta( $pau );
}
Então beleza, se eu fizer:
$eu->atira($pau, $gato);
vai funcionar certo? Pois o método atirar aceita Gato.
E se eu quiser fazer isso?
$eu->atira($pau, $cao);
Não irá funcionar pois o segundo parâmetro do método atirar aceita apenas Gato.
Você concorda comigo que Cao e Gato são alvos e implementam a interface Alvo?
Então se eu mudar no método acertar colocar Alvo ao invés de Gato vai funcionar?
Sim!
Então fica assim:
public function atira(Projetil $projetil, Alvo $alvo) {
$gato->acerta($pau);
}
PS: Essa explicação sobre o Alvo também serve para o Projetil, pois todos os projéteis implementam a interface Projetil.
Espero ter ajudado.
Parabéns João! Ótima didática.
Uma coisa que achei interessante, e que acredito nunca ter presenciado, era definir um "tipo" numa interface vazia.
Isso é muito louco!
Muito bom, agora começo a enxergar a real necessidade do uso de Interfaces.
Elas não servem para "amarrar" teu código, te obrigando a adicionar métodos e sim flexibilizar, alterando os comportamentos.
Mas cachorro quando a apanha faz "Caim, caim, caim..." :lol: