Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Vinicius Rangel

[Resolvido] interface e implements - OO

Recommended Posts

é galera eu não consegui desencanar disso e deixar isso em branco então resolvi parti para pratica a partir do exemplo do João nos tutoriais sobre polimorfismo.

 

o exemplo foi: atirei o pau no gato...

 

como é OO eu criei um objeto para cada coisa então vai ficar cumprido o post.

 

eu tenho a pessoa que no caso sou eu mas se fosse pra simplesmente copiar o exemplo aposto que não teria erros, enfim, qualquer pessoa pode atirar qualquer coisa em qualquer coisa.

 

então ficou

 

Pessoa.php

<?php
Class Pessoa implements projetil{
	private $nome;

	public function setNome($nome){
		$this->nome = $nome;
	}

	public function getNome(){
		return $this->nome;
	}

	public function atira(projetil $projetil){
	}
}
?>

 

projetil.php

<?php
interface projetil {

}
?>

 

pau.php

<?php
Class pau implements projetil {

}
?>

 

sapato.php

<?php
Class sapato implements projetil {

}
?>

 

<?php
Class pedra implements projetil {

}
?>

 

alvo.php

<?php
interface alvo{
	public function acerta(projetil $projetil);
}
?>

 

cachorro.php

 

<?php
Class cachorro {
	public function acerta implements alvo(projetil $projetil){
		echo "caim caim caim caim";
	}
}
?>

 

gato.php

<?php
Class gato {
	public function acerta implements alvo(projetil $projetil){
		echo "Miauuuuuuuuuuuuuuuuu";
	}
}
?>

 

janela.php

<?php
Class janela {
	public function acerta implements alvo(projetil $projetil){
		echo "a janela quebrou";
	}
}
?>

 

 

e finalmente a index onde eu chamo tudo isso, ai vem o grande x da questão.

 

percebam que minha pessoa implementa um projetil e também o sapato a pedra e o pau fazem essa implementação.

 

se eu incluir 2 páginas ele fala que eu não posso redeclarar o projetil.

 

se eu chamar apenas Pessoa ele não da nenhum erro agora se eu chamar Pessoa e Sapato ele vai me acusar erro.

 

alguma ideia do que acontece?

 

vlw galera.

Compartilhar este post


Link para o post
Compartilhar em outros sites

percebam que minha pessoa implementa um projetil e também o sapato a pedra e o pau fazem essa implementação.

hein?!

 

você JOGA uma pessoa em outras coisas ?

 

 

 

se eu incluir 2 páginas ele fala que eu não posso redeclarar o projetil.

sim, e realmente não deve. Inclua a interface projetil apenas uma vez.

 

você pode utilizar um autoload() ou então require_once

 

 

Eu não curto muito esses exemplos abstratos demais.. você chegou a ler o artigo do meu blog ? restou alguma dúvida depois ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

hein?!

 

você JOGA uma pessoa em outras coisas ?

 

é eu não faço isso, mas acho que seria engraçado. ahuahuahuahuuhaah

 

o meu pensamento foi: Uma pessoa joga coisas.

 

 public function atira(projetil $projetil){
               }

 

a ação dele é atirar mais ele tem que tirar alguma coisa então parti dessa linha.

 

o erro mesmo creio que você não entendeu

 

eu não estou chamando as minhas interfaces na index e sim em cada objeto que precisa dele ai depois só incluo o objeto.

 

Willian eu li mais acontece que eu pareço entender e não vejo utilidade então tentei aplicar...

 

eu li tanto do seu blog quando o que tem aqui no Imasters e eu estou aplicando para ver o conceito que eu estou aplicando é o correto.

Compartilhar este post


Link para o post
Compartilhar em outros sites

você JOGA uma pessoa em outras coisas ?

Eu iria falar a mesma coisa...

 

o meu pensamento foi: Uma pessoa joga coisas.

Você deve entender que, a interface projetil define que um objeto pode ser atirado/arremessado. Isso é o conceito, aplicado, do polimorfismo. Objetos diferentes (Sapato, Pau, Pedra) possam ser tratados de forma homogênea(da mesma forma). Uma vez que a classe Pessoa implementa a interface projetil, indica que a classe pessoa, nesse exemplo, também é um projetil. Assim ela pode ser atirada/arremessada.

 

o erro mesmo creio que você não entendeu

 

eu não estou chamando as minhas interfaces na index e sim em cada objeto que precisa dele ai depois só incluo o objeto.

Ambos, autoload e require_once, são soluções para isso. Eles evitarão que o arquivo seja chamado mais de uma vez e, assim sendo, declarado mais de uma vez.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Lembra do que eu falei no outro post, do outro tópico? Quando você compreender a relação do polimorfismo com as interfaces você mata a pau toda dúvida sobre elas.

 

Nesse exemplo Projetil é uma interface. Não foque apenas que todo objeto que implemente Projetil precisará obrigatoriamente implemetar o método Projetil::atira(), mas visualize que qualquer objeto que implemente essa interface será um Projetil por si só.

 

Essa afirmação pode ser verificada através do operador instanceof.

 

Mesmo que originalmente ele tenha sido concebido para verificar se um objeto é instância de outro, por herança, você verá que ele analisa também interfaces justamente pelo exposto acima.

 

Todo objeto que implemente uma interface é considerado, também, instância dela.

 

E como isso tem a ver com polimorfismo?

 

Veja que Pessoa, no método correto, não essa definição errônea (e sinistra :P) espera receber um Projetil e partir desse Projetil vai invocar o método Projetil::atira().

 

Para a classe Pessoa não importa qual Projetil será informado, o que importa é que seja um Projetil.

 

E é aí que entra o polimorfismo. Você pode informar QUALQUER objeto de QUALQUER classe contanto que eles se refiram à uma classe que implemente a interface Projetil.

 

Assim sua classe Pessoa sempre vai ter a certeza absoluta que o método atira() existirá, sem precisar ficar testando.

 

Veja o que foi feito com as classes Gato, Cachorro e Sapato. São três classes distintas, mas por implementarem a interface Projetil, todos são Projéteis válidos.

Compartilhar este post


Link para o post
Compartilhar em outros sites

aaa galerinha agora sim faz mais sentido, achava que era algo que complementava mais ou menos assim.

 

temos a interface projetil e o objeto pessoa e pedra e se implementarmos a interface ao objeto pessoa ele seria um objeto pessoa com possibilidade de receber um projetil onde as ações do objeto pode utilizar do mesmo ai acho que seria algo mais para herança né?

 

enfim agora comecei abrir bem minha mente eu vou pedir que o tópico continue aberto para caso eu tiver mais problemas não precisar abrir um novo.

 

vou começar a refazer..

 

Willian, Bruno e Gabriel as respostas dos 3 foram fundamentais.

 

obrigado

 

bom galera reabrindo aqui eu "terminei" o que tinha que fazer e me parece bem sensato agora principalmente depois do hangout de ontem.

 

segue o code.

 

projetil.php

<?php

interface Projetil {
}

?>

 

pau.php

require_once('Projetil.class.php');

class Pau implements Projetil {

}

 

pedra.php

<?php
require_once('Projetil.class.php');
class Pedra implements projetil {

}
?>

 

pedra.php

<?php
require_once('Projetil.class.php');

class Sapato implements Projetil {

}
?>

 

alvo.php

<?php
interface Alvo{
	public function acerta(Projetil $projetil);
}
?>

 

gato.php

<?php
require_once('Alvo.class.php');
class Gato implements Alvo{
	public function acerta(projetil $projetil){
		echo "Miauuuuuuuuuuuuuuuuu";
	}
}
?>

 

cachorro.php

<?php
require_once('Alvo.class.php');

class Cachorro implements Alvo{
	public function acerta(projetil $projetil){
		echo "caim caim caim caim";
	}
}
?>

 

janela.php

<?php
require_once('Alvo.class.php');

class Janela implements Alvo{
public function acerta(projetil $projetil){
		echo "a janela quebrou";
	}
}
?>

 

pessoa.php

<?php

Class Pessoa{
	private $nome;

	public function setNome($nome){
		$this->nome = $nome;
	}

	public function getNome(){
		return $this->nome;
	}

	public function atira(Projetil $projetil, Alvo $alvo){
		$alvo->acerta($projetil);
	}
}
?>

 

index.php

<?php
include 'Pessoa.class.php';
include 'Pedra.class.php';
include 'Pau.class.php';
include 'Sapato.class.php';
include 'Janela.class.php';
include 'Cachorro.class.php';
include 'Gato.class.php';

$pessoa = new Pessoa();
$pessoa->setNome('Roberto');

$pedra = new pedra();
$pau = new Pau();
$sapato = new Sapato();

$janela = new Janela();
$cachorro = new Cachorro();
$gato = new Gato();

$pessoa->atira($pau, $gato);

?>

 

parece correto pra mim ai eu lembro do neto dizendo sempre que o sistema não precisa saber de tudo no caso eu queria mostrar qual projetil foi jogado e em que foi jogado e também que jogou.

 

simplesmente jogar e ter a reação do animal(onomatopeia) ou o que aconteceu com a janela deu pra pegar esse ponto com o implements e a interface agora sempre falaram sobre visibilidade e no meu caso eu quero que essas informações venha até o usuário.

 

bom eu não terminei tudo pois quero saber se ideia inicial esta correta, e depois ainda se eu fosse passar todas as infos pro usuário elas ficariam no método acertar do gato? pois é a unica coisa que tem saída no meu código.

 

obrigado de novo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não é porque um método foi definido na interface e todas as classes que ela implementam o contém que você precisa invocá-lo.

 

Claro, na grande maioria das vezes é isso que vai acontecer, mas você não está restrito a isso. Você pode muito bem escrever qualquer outra coisa em Pessoa::atira().

 

E com get_class() por exemplo você obtém o nome da classe do objeto informado. Com isso você pode, como você mesmo quer, mostrar o que a Pessoa atirou e em quê:

 

class Pessoa {

   // ...

   public function atira( Projetil $projetil, Alvo $alvo ) {

       printf(

           'Atirando um (a) %s no (a) %s',

           get_class( $projetil ), get_class( $alvo )
       );
   }
}

Isso retornará, para o caso de ser informado Pedra e Gato, respectivamente: Atirando um (a) Pedra no (a) Gato

 

Existem outras possibilidades, como implementar o método mágico __toString() em cada uma das classes OU numa superclasse abstrata, da qual todas as concretas estendam, e simplesmente converter o objeto para uma string:

 

abstract class AbstractProjetil implements Projetil {

   public function __toString() {
       return get_class ($this );
   }
}

class Pedra extends AbstractProjetil {}

class Pessoa {

   // ...

   public function acert( Projetil $projetil, Alvo $alvo ) {

       printf( 'Atirando um (a) %s no (a) %s', (string) $projetil, (string) $alvo );
   }

}

E o efeito seria o mesmo.

 

Perceba que uma vez mesmo que apenas a classe abstrata implemente a interface, todas as classes que estenderem ela também serão Projéteis válidos.

 

Crédito Extra: Isso é útil quando, por exemplo, queremos permitir que vários objetos relacionados sejam contáveis e implementamos a interface Countable, onde apenas a classe abstrata implementaria o método em questão.

 

Continuando... Pode, ainda, criar um novo método de interface que, quando usado, permitisse descrever o objeto sendo atirado:

 

interface Projetil {

   public function describe();
}

class Pedra implements Projetil {

   public function describe() {
       return 'Pedra japonesa pontuda e avermelhada pesando 3 gramas';
   }
}

class Pessoa {

   // ...

   public function acert( Projetil $projetil, Alvo $alvo ) {

       printf( 'Atirando um (a) %s no (a) %s', $projetil -> describe(), (string) $alvo );
   }

}

O que produziria: Atirando um (a) Pedra japonesa pontuda e avermelhada pesando 3 gramas no (a) Gato

 

Lógico e evidente que você não faria isso pois ao definir o retorno do método Projetil::describe() dessa forma, estaria dizendo que TODAS as Pedras tem aquelas características, mas eu acho que você sacou isso por você mesmo, né?

 

:thumbsup:

Compartilhar este post


Link para o post
Compartilhar em outros sites

siim e era exatamente isso o que faltava...

 

para fechar com chave de ouro e passar para uma linguagem fácil podemos dizer que uma interface é um "sinônimo" do seu objeto.

 

exemplo:

 

interface veiculo{

}

class carro implements veiculo{

}

 

pois um carro é um veiculo e ainda ganho flexibilidade para definir outros tipos de veículos como motos e caminhões por exemplo.

 

obrigado pode dar closed aqui agora sim já entendi, claro que falta alguns pontos mais o que é e quando utilizar estou bem seguro..

 

abraços

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.