List X ArrayList (pq implementar uma interface?)  XML
Índice dos Fóruns » Java Básico
Autor Mensagem
pgnt
Debugger
[Avatar]

Membro desde: 18/01/2007 04:27:33
Mensagens: 57
Offline

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:

Se List é uma interface e ArrayList a implementa, não deveria ser a mesma coisa se fizéssemos isso:


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
victorwss
JWizard
[Avatar]

Membro desde: 18/12/2007 14:46:00
Mensagens: 2409
Localização: São Paulo - SP
Offline

Por um motivo simples: ArrayList não é a única coisa que implementa List. Se você quiser trocar a implementação, é muito mais simples fazê-lo se você sempre referenciar o tipo da interface.
Olhe estes dois exemplos:Vamos supor, que por qualquer motivo, você decida usar LinkedList, ou uma lista baseada em arrays ao invés de ArrayList:O que acontece? Se o tipo de retorno do método for ArrayList ao invés de List, você vai ter que mudar o tipo de retorno do método. Ao fazer isso, você pode acabar quebrando compatibilidade com outros lugares que usam o tipo de retorno ArrayList ao invés de List (como, por exemplo, o método mostraNumeros e provavelmente outros 500 lugares na sua aplicação), isso faz com que voce acabe tendo que ter todo o trabalho de mudar um a um esses lugares, ou então fazer uma gambiarra de criar um ArrayList no meio do caminho e copiar os elementos só porque você está usando o tipo errado e o compilador percebeu isto.
É esse que é o famoso (e pouco entendido) conceito "code to an interface". Isso significa, basicamente, "use o tipo mais genérico possível que você puder usar".

Victor Williams Stafusa da Silva

Bacharel em Ciência da Computação - UFMT // Especialista em Desenvolvimento Java - CEFET/MT // Doutorando em Ciência da Computação - IME-USP
SCJP 6.0 - 19/12/2007 - PASS - 88% // SCWCD 5 - 17/05/2008 - PASS - 79% // SCJA - 09/09/2008 - PASS - 96% // SCSNI - 30/06/2009 - PASS - 68% // SCBCD 5 - 31/05/2010 - PASS - 95%
Próximos: SCJD (encalhado com o projeto), SCEA parte I (estudando). Algum dia desses: SCMAD, OCA, SCEA e SCDJWS.

Computação: uma ciência holística e esotérica!
E então veio Deus a terra e disse aos homens: Não dividireis por zero.
XML is a giant step in no direction at all. (Erik Naggum)
Arquitetura de sistemas: Eu prefiro ser essa metamorfose ambulante do que ter aquela velha opinião formada sobre tudo.
Diga não as drogas: Não use java.util.Vector.
Cuidado: Este usuário pode ter temperamento agressivo.

Always code as if the person who will maintain your code is a maniac serial killer that knows where you live.
I am the maniac serial killer that knows where you live who will maintain your code.


É impossível falar de CMMI (Capability Maturity Model Integration) sem saber o que é CIMM (Capability Im-Maturity Model).


Se você escreve "concerteza", "concerteza" você andou matando aulas de português.
[MSN]
Lavieri
GUJ Master
[Avatar]

Membro desde: 27/01/2004 13:39:31
Mensagens: 1851
Localização: João Pessoa / PB
Offline

Pense na coisa + ou - como uma peneira...

se vc afirma por exemplo em um método seu, que vc ker um ArrayList, vc esta reduzindo as possibilidades, so vai aceitar um ArrayList ou algo que venha dele, isso vai depender da sua aplicação, se ela depende diretamente que vc tenha uma ArrayList e não uma List, ou seja, se existem métodos que só existe em ArrayList e que vc precisa usar, então vc deve referenciar pela ArrayList e não pela List...

digamos que vc tenha um Objeto chamado de Pessoa, e que este objeto tenha uma lista de Telefones então vc teria nele algo assim...



blz tua classe ta funcionando perfeitamente... porem digamos agora que vc começou a usar Hibernate, para ler os dados de um banco de dados, e que vc pessa pra ele ler a lista de pessoas, o Hibernate retorna um objeto List, porem esse objeto List do hibernate é um HibernateList e não vem de ArrayList... portanto ao fazer essa consulta, vc não consiguirar usar algo como pessoa.setTelefones(HibernateUtils.list(Pessoa.class)), para tal vc teria q criar uma ArrayList e transfir os dados do HibernateList para sua lista...

agora se tua classe estiver pronta para receber List no lugar de ArrayList ... qualquer que seja a implementação da interface List... vc poderar aceitar...



veja q nesse exemplo acima, vc continua usando ArrayList no seu campo telefones.... veja que vc ainda poder fazer pessoa.setTelefones(arrayList) porem vc aumentou as possibilidades aceitando tb pessoa.setTelefones(qualquerList) ...

isso é uma questão de necessidade... c vc so precisa dos métodos inerentes a List, não há motivos para restringir a ArrayList

Sun Certified Java Programmer (SCJP 6)

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999

Meu blog -> http://blog.tomazlavieri.com.br/
[ICQ]
sergiotaborda
GUJ Expert
[Avatar]

Membro desde: 22/03/2005 20:57:48
Mensagens: 3433
Offline

pgnt wrote: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:

Se List é uma interface e ArrayList a implementa, não deveria ser a mesma coisa se fizéssemos isso:



Java é OO e tem uma propriedades chamada Polimorfismo. Em especial uma chamada Variável Polimórfica.

É boa prática declarar a sua variável de forma polimórfica. Ou seja, delcará-la com o tipo mais abstrato que ainda faz o serviço.
No caso, List é o tipo mais abstrato que faz o serviço ( mas poderia ser Collection, por exemplo)

Esta prática é conhecida como "programar para interfaces" mas nada é mais além de usar OO e polimorfismo para ter um codigo mais simples e de mais fácil manutenção.

[WWW]
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Diferentemente do C++ e do C#, não há perda de desempenho em referenciar algo através de sua interface em vez da classe.
O JIT (Just-In-Time Compiler) do Java faz algumas otimizações e uma chamada "virtual" (usando a terminologia do C++ e do C#) é transformada em uma chamada não-virtual se isso for possível no seu programa (como é o caso do seu exemplo, onde uma variável já recebe um valor de uma determinada classe e o tipo do objeto não muda em tempo de execução).
[WWW]
GouverMXT
JavaGuru
[Avatar]

Membro desde: 19/03/2007 15:58:06
Mensagens: 233
Offline

Lavieri wrote:
isso é uma questão de necessidade... c vc so precisa dos métodos inerentes a List, não há motivos para restringir a ArrayList


E mesmo que se venha a precisar de métodos inerentes unicamente à ArrayList ainda se pode fazer um castdown.

Rails. It just works.
Malkav.Felipe
JavaBaby
[Avatar]

Membro desde: 17/11/2008 14:00:29
Mensagens: 94
Localização: Capão da Canoa - RS
Offline

Ola pessoal... venho estudando java a algum tempo e com as respostas contidas nessa discução, eu to conseguindo entender um pouco melhor a expressão "code to an interface"..

Mas através dos meus estudos e pesquisas surgiram umas outras duvidas...


Gostaria da opinião dos mais experientes e me responder as seguintes questões:

Podemos "modelar" um sistema apenas utilizando interfaces? E depois só criarmos um implementação para cada uma deslas? Éssa é a ideia não é?
É certo afirmar então, que uma boa pratica de POO é que um objeto, não digo sempre, mas " quase sempre" deveria implementar uma interface?(pq deve ter casos especificos que nessecite o contrario né?) ou estou superestimando o uso de delas (interfaces)?

Valeu pela atenção pessoal.


Felipe

Em busca de conhecimento...
[Email] [WWW] [MSN]
Malkav.Felipe
JavaBaby
[Avatar]

Membro desde: 17/11/2008 14:00:29
Mensagens: 94
Localização: Capão da Canoa - RS
Offline

Por favor pessoal.... esclareçam minhas duvidas

Em busca de conhecimento...
[Email] [WWW] [MSN]
Bruno Laturner
GUJ Expert
[Avatar]

Membro desde: 18/02/2008 16:17:53
Mensagens: 3002
Offline

Malkav.Felipe wrote: Podemos "modelar" um sistema apenas utilizando interfaces? E depois só criarmos um implementação para cada uma deslas? Éssa é a ideia não é?

É certo afirmar então, que uma boa pratica de POO é que um objeto, não digo sempre, mas " quase sempre" deveria implementar uma interface?(pq deve ter casos especificos que nessecite o contrario né?) ou estou superestimando o uso de delas (interfaces)?

Não. Não há sentido em usar interfaces pra tudo, pode ser que alguns de seus objetos sejam inerentemente concretos.

Sem falar que modelamos para conceitos, não para linguagens. Não importa que Telefone seja interface ou classe, o que importa é que queremos um Telefone.

Enfim, não procure polimorfismo onde não tem, e seja simples e pragmático, se ficar fazendo só interfaces, vai esquecer que tem um sistema concreto pra fazer.

A resposta acima foi achada em menos de 5 minutos no google.
The prisoner falls in love with his chains. --E.W. Dijkstra
[WWW]
Lavieri
GUJ Master
[Avatar]

Membro desde: 27/01/2004 13:39:31
Mensagens: 1851
Localização: João Pessoa / PB
Offline

Uma coisa que pode te ajudar a entender quando é necessario uma interface...

pense da seguinte forma, interface representa um comportamento... vc pode ter varios objetos destintos, onde cada um destes objetos tem uma Hieraquia propia, porem pode exister um comportamento em comum entre eles, se esse comportamente te interessar essa é a hora de usar interfaces...

Por exemplo, "Fazer Som" já imaginou quantos objetos distintos podem existir no mundo que são capazes de emitir som ?? é impossivel fazer isso por herança, mais digamos que vc precise por alguma rotina, emitir o som de diversos objetos ?? como fazer ?? como ter uma sacola com uns 40 ... 500 ... 1000 tipos diferentes de objetos e conseguir tocar o som de todos ?? quando vc vai num aparelho de DVD o que vc procura pra tocar som ?? uma imagem + ou - assim |> akele botãozinho de play ... pois é aquilo é uma interface, interface é uma forma de comunicação comum a varios objetos...

Em programação isso pode ser feito, disponibilizando um contrato por exemplo...


pronto agora vc tem um contrato, uma forma de comunicar a alguem como vc interpreta que aquile objeto Emite som, ali esta o seu contrato... agora vc pode programar, de forma generica, pra tocar o som de qualquer objeto



o que esse método faz ?? ele pega uma lista de objetos, verifica um por um, se ele assina o contrato de EmtidorDeSom, caso positivo, ele faz um cast, do objeto, para um emitidor de som, ele simplismente esquece tudo que o objeto pode representar, e olha apenas para a interface dele de emitidor de som... nessa interface ele ativa o método
playSom() ... e mesmo sem saber que objeto se trata, ele consegue emitir o seu som...

.........

E agora sabendo disso... como criar um aparelho proprio ? que emite som ?? ... digamos que vc seja louco e projetou um bone que emite som... vc não precisa descender o seu bone direto de um MP3 player... basta vc em seu bone que emite som, assinar o contrato de emitir som...



.......

Pronto, agora qualquer objeto que conheça o contrato EmitidorDeSom, pode tocar o som do seu Bone, mesmo sem conhecer o funcionamento dele, e mesmo sem obriga-lo a descender de um Tocador de som genérico... é pra isso que existem as interfaces, para Definir contratos uteis ao seu modelo (ou comportamentos uteis ao seu modelo)...

..........

Um exemplo, que eu uso muito nos meus modelos é uma interface chamda Sizable eu tenho varios objetos no meu modelo que tem um referencial de quantidade, como estoque (que tem quantidade), entre varios outros objetos uteis.... para ter uma forma comum de verificar o tamanho de varios objetos eu criei essa interface



toda calsse no meu modelo, que tem quantidade, eu assino o contrato de Sizable, e implemento os 2 métodos... assim posso ter métodos genericos, que testam consistencia dos meus objetos, por exemplo, eu para alguns objetos, preciso verificar se ele esta vazio e se estiver, lançar uma exceção de erro, por não aceitar objetos vazio eu tenho um método na minha classe Consistences.notEmpty(Sizable obj); onde ele verifica se o tamanho é vazio e se for, lança uma exceção... isso é um exemplo pratico, que me serve, e vc pode criar os seus...

This message was edited 9 times. Last update was at 18/03/2009 18:13:29


Sun Certified Java Programmer (SCJP 6)

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
-Martin Fowler et al, Refactoring: Improving the Design of Existing Code, 1999

Meu blog -> http://blog.tomazlavieri.com.br/
[ICQ]
Malkav.Felipe
JavaBaby
[Avatar]

Membro desde: 17/11/2008 14:00:29
Mensagens: 94
Localização: Capão da Canoa - RS
Offline

Lavieri

PERFEITA A SUA EXPLICAÇÃO! Muito obrigado pela atenção cara.... pude compreender muito melhor o conceito de interface agora.... mesmo com esse seu exemplo do BoneSonzera


Cara... obrigado de novo!!

Em busca de conhecimento...
[Email] [WWW] [MSN]
 
Índice dos Fóruns » Java Básico
Ir para:   
Powered by JForum 2.1.8 © JForum Team