List X ArrayList

Java

09/04/2009

Olás Já andei pesquisando e sei como trabalhar com os Arrays, mas o que eu não entendo (e não encontro explicação) é por que normalmente há uma referência da interface List para o ArrayList. tipo:
List<String> words = new ArrayList<String>();
Se List é uma interface e ArrayList a implementa, não deveria ser a mesma coisa se fizéssemos isso:
ArrayList<String> words = new ArrayList<String>();
Já que "ArrayList implements List", já não estaríamos herdando essa interface instanciando ArrayList? Parece bizarro é instanciar uma interface... (ou preciso estudar mais rs) mas não vejo essas referências a interfaces nos códigos por aí. vlw
Paulo

Paulo

Curtidas 0

Respostas

Carlos Heuberger

Carlos Heuberger

09/04/2009

[quote="pgnt"]Olás Já andei pesquisando e sei como trabalhar com os Arrays, mas o que eu não entendo (e não encontro explicação) é por que normalmente há uma referência da interface List para o ArrayList. tipo:
List<String> words = new ArrayList<String>();
Se List é uma interface e ArrayList a implementa, não deveria ser a mesma coisa se fizéssemos isso:
ArrayList<String> words = new ArrayList<String>();
Já que "ArrayList implements List", já não estaríamos herdando essa interface instanciando ArrayList? Parece bizarro é instanciar uma interface... (ou preciso estudar mais rs) mas não vejo essas referências a interfaces nos códigos por aí. vlw
Oi, não é exatamente a mesma coisa (usar o ArrayList), mas funciona. A ArrayList tem (no mínimo) os mesmos métodos e funcionalidade que a List, mas o contrário não é necessariamente verdadeiro. Existem pelo menos duas razões para declarar a variável como sendo List: [list="1"] [*]mais fácil mudar de ArrayList para outra classe que implementa a List (LinkedList, Vector,...). Isso é importante principalmente para argumentos de métodos. Não tem que criar outro método ou alterar a API para usar as outras implementações da List. [*]para deixar claro ([i]documentado[/i]) que [i]apenas [/i]necessita da funcionalidade da List e não a funcionalidade específica da ArrayList. Fica (IMHO) é um pouco mais orientado a objetos. [/list] []]
GOSTEI 0
Ricardo Staroski

Ricardo Staroski

09/04/2009

[quote="pgnt"]não vejo essas referências a interfaces nos códigos por aí
Se existe uma interface para os objetos que você manipula, é aconselhável utilizar sempre referência para as interfaces e não para as implementações. No seu exemplo pode parecer estranho, mas imagina algum método que receba uma lista como parâmetro ou que devolva uma lista, já pensou se você marca o parâmetro ou retorno como sendo do tipo ArrayList ao invés de List, você vai obrigar todo mundo a ter que utilizar a classe ArrayList, cadê a reusabilidade? E se eu tiver minha própria implementação de List, que não é um ArrayList, como é que fica? Não precisa nem ser uma implementação de List feita por mim, basta eu ter algum código que utilize outras implementações de List como por exemplo Vector ou LinkedList. Lembre-se, se uma classe implementa alguma interface, procure referenciar sempre essa interfaces.
GOSTEI 0
Everton Barros

Everton Barros

09/04/2009

[quote="pgnt"] Já andei pesquisando e sei como trabalhar com os Arrays, mas o que eu não entendo (e não encontro explicação) é por que normalmente há uma referência da interface List para o ArrayList.
Para entender um pouco mais, de uma estuda sobre [url=http://www.google.com.br/search?hl=pt-BR&ei=5C6cSbmrMISENfqH4ZUF&sa=X&oi=spell&resnum=1&ct=result&cd=1&q=Heran%C3%A7a+Java&spell=1]Herança[/url] ou [url=http://www.google.com.br/search?hl=pt-BR&q=Generaliza%C3%A7%C3%A3o+Java&btnG=Pesquisar&meta=]Generalização[/url]. Boa sorte!
GOSTEI 0
Paulo

Paulo

09/04/2009

Obrigado pelo retorno pessoal. Eu entendi os benefícios, mas a sensação de estar fazendo algo bizarro é que, quando instaciamos um objeto, estamos explicitamente fazendo uma referência dos dados na memória e, instanciando uma interface, não parece ter esse efeito. A impressão é que faria mais sentido ou, pareceria mais 'concreto', instanciar uma CLASSE mais genérica que ArrayList no caso, mas não uma interface (a não ser que o Java faça isso de forma implícita). Pra resumir, parece que estamos levando a forma do bolo e não o bolo pra mesa do café... vlw abs
GOSTEI 0
Ricardo Staroski

Ricardo Staroski

09/04/2009

[quote="pgnt"]...quando instaciamos um objeto, estamos explicitamente fazendo uma referência dos dados na memória e, instanciando uma interface, não parece ter esse efeito... ...faria mais sentido ou, pareceria mais 'concreto', instanciar uma CLASSE mais genérica que ArrayList no caso, mas não uma interface...
Mas você NUNCA instancia uma interface, interfaces são abstratas, você instancia uma classe que a implementa.
GOSTEI 0
Alexandre Viriato

Alexandre Viriato

09/04/2009

[quote="pgnt"] Eu entendi os benefícios, mas a sensação de estar fazendo algo bizarro é que, quando instaciamos um objeto, estamos explicitamente fazendo uma referência dos dados na memória e, instanciando uma interface, não parece ter esse efeito.
E como você faria para manipular esses dados na memória? Através dos métodos. É isso que você garante quando programa para uma interface e não para uma implementação em específico. Imagine que no seu sistema você resolveu trabalhar com Vector e tem os códigos assim:
Vector lista = new Vector();
Mas, você percebeu que seu sistema está lento. Como nós sabemos, a classe Vector é sincronizada (tem os métodos sincronizados) e. por isso é mais lenta. Pesquisando você descobriu que existe a classe ArrayList que tem as mesmas características de Vector, porém, sem ser sincronizada, sendo assim, mais rápida. Bom, você já achou a solução: Trocar de Vector para ArrayList. Mas agora você vai ter que sair modificando [b]todo[/b] seu código para:
ArrayList lista = new ArrayList();
Sem contar nas alterações dos codigos que usam essa lista.E se você resolver usar outro tipo de lista? Vai sair alterando todo o código novamente? (isso sim seria completamente bizarro). Dessa forma, se você fizer
List lista = new Vector();
bastaria trocar por
List lista = new ArrayList();
Sem ter que alterar os códigos que usam a lista. (Na verdade o ideal seria usar uma fábrica, assim você só mudaria nela, mas enfim). [url="http://javafree.uol.com.br/viewtopic.jbb?t=871898"]Aqui[/url] tem uma thread sobre interfaces. Vale a pela dar uma lida.
GOSTEI 0
Paulo

Paulo

09/04/2009

Blz, tks! Apesar dessa flexibilidade e padronização graças à interface, não teríamos problemas se as instâncias estivessem métodos diferentes além daquelas definidas na interface? ex
 interface I{  void acaoA();}

class X implements I{
  void acaoA(){ ... }
  void acaoB(){ ... }
}

class Y implements I{
  void acaoA(){ ... }
  void acaoC(){ ... }
}
Agora, imaginem que eu tenho instancias dessas classes e aconteça de mudar (como pode acontecer com ArrayList e Vector nos exemplos, fazendo uma referência pra tipos de objetos diferentes).
I obj1 = new X();
I obj2 = obj1;

obj2.acaoC();
Neste caso estou buscando um método que pertence a outra classe, mas que implementa a mesma interface. Isso não é um problema? (e deixa inconsistente a flexibilidade da interface?).
GOSTEI 0
Alexandre Viriato

Alexandre Viriato

09/04/2009

[quote="pgnt"]Blz, tks! Apesar dessa flexibilidade e padronização graças à interface, não teríamos problemas se as instâncias estivessem métodos diferentes além daquelas definidas na interface? ex
 interface I{  void acaoA();}

class X implements I{
  void acaoA(){ ... }
  void acaoB(){ ... }
}

class Y implements I{
  void acaoA(){ ... }
  void acaoC(){ ... }
}
Agora, imaginem que eu tenho instancias dessas classes e aconteça de mudar (como pode acontecer com ArrayList e Vector nos exemplos, fazendo uma referência pra tipos de objetos diferentes).
I obj1 = new X();
I obj2 = obj1;

obj2.acaoC();
Neste caso estou buscando um método que pertence a outra classe, mas que implementa a mesma interface. Isso não é um problema? (e deixa inconsistente a flexibilidade da interface?).
Esse código não compila, por que você só tem acesso aos membros definidos no tipo da variável e não da instância ao qual ela faz referência. Ou seja, obj2 é do tipo I e, com isso, não importa que ela esteja referenciando um objeto da classe X, ela só conhece o que foi definido na interface I. Como você definiu a acaoC na [b]classe[/b] Y, e não em uma interface, você só conseguirá acessar esse método se definir uma variável como sendo do tipo da classe. Em resumo, continuou programando para uma implementação e não para uma interface.
GOSTEI 0
Paulo

Paulo

09/04/2009

Então, neste caso eu tenho que confiar que, Vector e ArrayList por exemplo, não implementem métodos além dos definidos da interface, do contrário posso ter um problema de inconsistência quando os instanciar, certo? (...por analogia devo fazer o mesmo com minha aplicação quando definir uma interface)
GOSTEI 0
Alexandre Viriato

Alexandre Viriato

09/04/2009

[quote="pgnt"] Então, neste caso eu tenho que confiar que, Vector e ArrayList por exemplo, não implementem métodos além dos definidos da interface, do contrário posso ter um problema de inconsistência quando os instanciar, certo? (...por analogia devo fazer o mesmo com minha aplicação quando definir uma interface)
Acho que os conceitos de interface e principalmente do que é "programar para uma interface e não para uma implementação" ainda não estão muito claros pra você, sendo assim, sugiro que dê uma boa estudada sobre esses assuntos. Com relação à sua pergunta, você não tem que confiar no sentido de torcer, tem que confiar no sentido de saber. O que nós tentamos dizer pra você até agora é que, você não deve programar pensando em Vector e nem em ArrayList, por que ambas são [b]classes que implementam a interface List[/b]. Você tem que programar pensando em List. Dessa forma você pode confiar que, QUALQUER CLASSE que implemente a interface List poderá ser usada. A partir do momento que você programa pensando em Vector ou em ArrayList (ou em qualquer outra classe em específico) estará programando para uma implementação e amarrando seu código nessa implementação. É claro que existem situações onde isso pode ser necessário, por isso foi dito que o projeto deve ser muito bem pensando.
GOSTEI 0
Paulo

Paulo

09/04/2009

Concordo que preciso estudar mais porém, o material que tenho não cobria essas dúvidas... pela internet não achei nada melhor que a conversa que tivemos por aqui. O que me deixou confuso é que se pode implementar mais métodos na classe 'concreta' do que as definidas pela interface, isso pode ser muito perigoso se não for bem pensado (que pode cair no caso de inconsistência que estava falando). Mas no fim das contas entendi que a Interface, além de estabelecer/regrar métodos de um contexto, pode ser referenciado de forma a abstrair um objeto da implementação. Obrigado pelos esclarecimentos e a paciência com o novato aqui rs abs
GOSTEI 0
Alexandre Viriato

Alexandre Viriato

09/04/2009

[quote="pgnt"] O que me deixou confuso é que se pode implementar mais métodos na classe 'concreta' do que as definidas pela interface, isso pode ser muito perigoso se não for bem pensado (que pode cair no caso de inconsistência que estava falando).
É por isso que uma classe pode implementar mais de uma interface. Com isso, você pode garantir que, todos os métodos de uma classe façam parte de uma (ou outra) interface.Mas, ai cairemos novamente na discussão sobre os cuidados do projeto. Boa sorte!
GOSTEI 0
Leonardo Aguirre

Leonardo Aguirre

09/04/2009

Eu estou tendo um problema nesta linha de comando alguem poderia me ajudar? System.out.println((listCarro.get(i).getStatusCarro));
GOSTEI 0
Ricardo Staroski

Ricardo Staroski

09/04/2009

[quote="Leonardo Aguirre"]Eu estou tendo um problema nesta linha de comando alguem poderia me ajudar? System.out.println((listCarro.get(i).getStatusCarro));
Qual o erro? Se 'getStatusCarro' é um método, então deveria ser assim:
System.out.println((listCarro.get(i).getStatusCarro()))
GOSTEI 0
POSTAR