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.
É 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();
}
}
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.
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.
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.
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.
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.
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…
“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”.
[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.