Polimorfismo?

Pessoal,

Estou começando em Java, e tenho uma dúvida quanto a atribuição de tipos… não sei se me expressei bem, mas abaixo explico melhor…

por exemplo o list… o list é uma interface certo?? logo, eu sei que ela não pode ser instanciada…

como exemplo o código List a = new ArrayList();

a dúvida é… pq utilizamos um objeto do tipo List, ao invés de utilizar diretamente um ArrayList???

sei q isso tb pode acontecer com classes extendidas (herança)… sendo q a classe ‘filha’ instancia a classe ‘pai’…

Grato

Marcos

Boa pergunta… também tenho essa duvida… se alguém souber ajuda ai.

É verdade… nunca tinha pensado nisso. Mas eu uso isso às vezes, principalmente com Calendar:

Calendar c = new GregorianCalendar();

[quote=mgarcia]Pessoal,

Estou começando em Java, e tenho uma dúvida quanto a atribuição de tipos… não sei se me expressei bem, mas abaixo explico melhor…

por exemplo o list… o list é uma interface certo?? logo, eu sei que ela não pode ser instanciada…

como exemplo o código List a = new ArrayList();

a dúvida é… pq utilizamos um objeto do tipo List, ao invés de utilizar diretamente um ArrayList???

sei q isso tb pode acontecer com classes extendidas (herança)… sendo q a classe ‘filha’ instancia a classe ‘pai’…

Grato

Marcos[/quote]

Por uma questão de boas práticas. Quando trabalhamos orientado a interfaces, estamos sempre aptos a promover o polimorfismo, a escolha da implementação, facilidade nos testes e baixo acoplamento.

Veja bem, um dia você decide criar um componente mais específico ao ArrayList, e se, caso você esteja utilizando um container de IoC e seu código esteja dentro dos padrões, você apenas altera o “setup” do seu container, sem precisar sair caçando todos os lugares do código onde você tem ArrayList.

Um bom estudo para isso é entender bem como funciona a Inversão de controle com injeção de dependências: http://www.martinfowler.com/articles/injection.html

Oi MGarcia

É uma boa pergunta, e é importante entender a resposta. O polimorfismo é a ferramente essencial para diminuir o acoplamento entre as suas classes.

Vou copiar um texto da apostila da caelum, do final do capitulo de Collections (exercicios), que fala exatamente disso:

	Repare que, se você declarar a coleção e der newassim:
	
	[code]
		Collection<Integer> teste = new ArrayList<Integer>();
	[/code]
	
	em vez de
	
	[code]
		ArrayList<Integer> teste = new ArrayList<Integer>();
	[/code]
	
	É garantido que vai ter de alterar só essa linha para substituir a implementação por 
	HashSet ou LinkedList ou qualquer outra! Estamos aqui usando o polimorfismo para nos proteger que mudanças de 
	implementação venham nos obrigar a alterar muito código. Mais uma vez: ::programe voltado a 
	interface, e não à implementação::! Esse é um **excelente** exemplo de bom uso de interfaces, 
	afinal, de que importa como a coleção funciona? O que queremos é uma coleção qualquer, 
	isso é suficiente para os nossos propósitos! Nosso código está com **baixo acoplamento**
	em relação a estrutura de dados utilizada: podemos trocá-la facilmente.
	
	Esse é um código extremamente elegante e flexível. Com o tempo você vai reparar que
	as pessoas tentam programar sempre se referindo a essas interfaces menos específicas:
	os métodos costumam receber e devolver Collections, Lists e Set
	em vez de referenciar diretamente uma implementação. É o mesmo que ocorre
	com o uso de InputStreame OutputStream: eles são o suficiente, não
	há porque forçar o uso de algo mais específico.		
	
	Obviamente, algumas vezes não conseguimos 
	trabalhar dessa forma e precisamos usar uma interface mais específica ou mesmo nos referir ao 
	objeto pela sua implementação para poder chamar alguns métodos. Por exemplo, 
	TreeSet tem mais métodos que os definidos em Set assim como LinkedList em relação a 
	List.

No polimorfismo, obrigatoriamente é necessário existir herança. No entanto toda classe que possui mais de 1 subclasse é considerada polimórfica.
No entanto o que ocorre é a instância de um objeto filho na referência da superclasse. E nunca o contrário.

Exemplo:


class Animal {

}

class Cavalo extends Animal {

}

public class Teste {

    public static void Main(String [] args) {

        Animal animal = new Cavalo();

    }
}

Não testei o código, porém a idéia é essa :smiley:

[quote=mgarcia]Pessoal,

Estou começando em Java, e tenho uma dúvida quanto a atribuição de tipos… não sei se me expressei bem, mas abaixo explico melhor…

por exemplo o list… o list é uma interface certo?? logo, eu sei que ela não pode ser instanciada…

como exemplo o código List a = new ArrayList();

a dúvida é… pq utilizamos um objeto do tipo List, ao invés de utilizar diretamente um ArrayList???

sei q isso tb pode acontecer com classes extendidas (herança)… sendo q a classe ‘filha’ instancia a classe ‘pai’…

Grato

Marcos[/quote]

Ola MGarcia as interfaces ajudam você a reduzir o acoplamento(dependencia de outras classes), para entender de uma olhada no padrão de projeto Factory ou qualquer outro semelhante.

Obrigado galera…

Não estava entendendo, mas com essas explicações já deu uma clareada legal… vou estudar um pouquinho mais pra entender direitinho…

valeu pela atenção!!

Achei a resposta do Paulo Silveira muito boa, só vou reforçar com um detalhe.

Não pense no seu código como um Monolito, você terá várias classes com diferentes funcionalidades.

Eis um exemplo besta:

class Algo{
       public Collection<String> pegaLista(){
              Collection<String> x;
              //código pra criar a coleção
              return x;
       }
}

Vc tem uma outra classe:

class OutroAlgo{
       public void fazAlgo(){
              Collection<String> x = new Algo().pegaLista();
              for(String str: x){
                     // trabalha com os elementos...
              }
       }
}

Perceba que a minha classe OutroAlgo não se importa com qual o tipo da coleção, desde que seja uma coleção que tenha os métodos que uma Collection pede. Isso diminui o acoplamento das suas classes. Se vc um dia precisar alterar a classe Algo, só vai mudar ela e mais ninguem.

Implementar uma interface não é herança.

Veja o exemplo do CharSequence, List, Set, Map… :wink:

Implementar uma interface não é herança.

Veja o exemplo do CharSequence, List, Set, Map… ;-)[/quote]

Como é que você vai sobrescrever um método que não existe? Complicado hien, não existe polimorfismo sem herança, obrigatoriamente existe herança, implicitamente.

Em resumo … Usando uma interface tu pode “brincar” com todas as classes que implementaram a interface e não preso a uma implementação especifica.

Bem vindo ao mundo java … Ge …

Implementar uma interface não é herança.

Veja o exemplo do CharSequence, List, Set, Map… ;-)[/quote]

Complicado hien, não existe polimorfismo sem herança![/quote]

Implementar != de Herdar.
Herança tem a ver com reaproveitamento de codigo e especialização em uma cadeia de classes.
Iplementar(interfface) tem a ver com seguir um contrato, nao tem nada a ver com heranca.
Polimorfismo tem a ver com comportamentos diferentes de um mesmo objeto, não como importa como esse comportamento é feito, seja por heranca ou implementação.
Entao, sim existe polimorfismo sem herança.

[]´s

Implementar uma interface não é herança.

Veja o exemplo do CharSequence, List, Set, Map… ;-)[/quote]

Como é que você vai sobrescrever um método que não existe? Complicado hien, não existe polimorfismo sem herança, obrigatoriamente existe herança, implicitamente.[/quote]

E como eu sobrescrevo um metodo que não foi implementado ainda(interface).
Quando vc implementa um interface, vc implementa os metodos, vc NÂO sobrescreve.
De uma lida sobre sobrescrita de metodos.

[]´s

http://www.guj.com.br/posts/list/49267.java#258941

Implementar uma interface não é herança.

Veja o exemplo do CharSequence, List, Set, Map… ;-)[/quote]

Complicado hien, não existe polimorfismo sem herança![/quote]

Implementar != de Herdar.
Herança tem a ver com reaproveitamento de codigo e especialização em uma cadeia de classes.
Iplementar(interfface) tem a ver com seguir um contrato, nao tem nada a ver com heranca.
Polimorfismo tem a ver com comportamentos diferentes de um mesmo objeto, não como importa como esse comportamento é feito, seja por heranca ou implementação.
Entao, sim existe polimorfismo sem herança.

[]´s
[/quote]

O Fato de você não ter implementação em interfaces, não significa que não se aplica herança, O mesmo acontece com classes Abstratas, onde você pode implementar alguns métodos da interface, a unica diferença é a forma que foi criada a sintaxe para ficar facil o compreendimento, faça o teste, “É um” qualquer classe que implementar uma interface passa no teste é um tipo de…

só reforçando o básico do básico:

“extends” e “implements” sao coisas bem diferentes… nao existe herança de interfaces, bem como implementacao de classes… um poliformismo de interfaces não é “poliformismo por herança”.

jopss

[quote=vanzella]
O Fato de você não ter implementação em interfaces, não significa que não se aplica herança, O mesmo acontece com classes Abstratas, onde você pode implementar alguns métodos da interface, a unica diferença é a forma que foi criada a sintaxe para ficar facil o compreendimento, faça o teste, “É um” qualquer classe que implementar uma interface passa no teste é um tipo de…[/quote]

Não, isso não foi feito so p/ “facilitar”, simplesmente pq são conceitos diferentes.
Estou falando de conceito, não como o bytecode é gerado.
Passa no teste “É UM” não quer dizer nada, posso fazer:

class Carro extends Pessoa {
}

e vai passar no teste “é um”.

Interfaces nada tem a ver com Herança. Isso sempre gerou confusão. Lembro de quando diziam que interfaces no java vieram para solucionar o fato de não haver heranca multipla. Não tem nada a ver. Repito, Heranca e Interfaces são conceitos coompletamente diferentes.

[]´s

Ok já chega, não quero polemisar isso aqui, até por que não foi esse o assunto do topico, voltemos ao foco.

obrigado por me corrigirem galera
não lembrei do fator (interfaces) :slight_smile:
vou fixar melhor o conceito!