Classes, por que instanciar piliformicamente

Olá a todos,

Estudando sobre Coleções e Arrays, tive a seguinte dúvida:
Qual a vantagem em instanciar um ArrayList (ou qual quer outra classe) poliformicamente?
por exemplo, por que devemos instanciar uma lista da seguinte forma:

List list = new ArrayList();

e não desta forma:

ArrayList list = new ArrayList();

…uma vez que instanciamos um ArrayList utilizando a SuperClasse perdemos acesso aos métodos exclusivos de ArrayList que não tenham a assinatura definida da SuperClasse (interface List).
Sendo assim porque essa abordagem é a mais usual?

Isso não é instanciar polimorficamente. Nem existe isso.
O que se está fazendo é criando um variável do tipo referência para um List e inicializando-a com uma referência para um ArrayList. Nesse caso há um upcast implícito, visto que o tipo do objeto é do tipo da referência.
Algo assim:

List<String> list = (List<String>) new ArrayList<String>();

Declarar com o tipo mais geral é uma boa prática, não uma obrigatoriedade.
Imagine se vc tiver um método que receba um List, vc pode passar para ele qualquer coisa que implementa uma List, ou seja, há garantia que o objeto passado se comportará como uma lista, visto que dentro do método só poderão ser usados os métodos do tipo da referência.

[]'s

Eae David, tudo bem?
Bom foi mau usar o termo “instanciar polimorficamente”, me referia à instanciar um ArrayList poliformicamente, mas enfim…
vlw pela resposta. :smiley:

[quote=ldsant]Eae David, tudo bem?
Bom foi mau usar o termo “instanciar polimorficamente”, me referia à instanciar um ArrayList poliformicamente, mas enfim…
vlw pela resposta. :smiley: [/quote]
Olá, seja bem vindo!

Ainda assim vou insistir, não existe “instanciar um ArrayList polimorficamente”.
Polimorfismo é a execução de um método dependendo da implementação, ou seja, cada classe que implementa um método herdado vai executar aquele método de uma forma específica. A execução depende do objeto instanciado e não do tipo referência. Da referênca a obrigatoriedade é o nome e a assinatura do método.

Exemplo. Tanto ArrayList quanto LinkedList implementam a interface List, sendo assim, precisam, obrigatoriamente, implementar o método add.
A classe ArrayList faz o “add” de uma forma, enquanto LinkedList provavelmente faz de outra forma. O que importa é que o método funciona, ou seja, adiciona um item na lista. Então, se você tem uma variável do tipo List vc pode atribuir a ela um ArrayList ou uma LinkedList (pense novamente no método) e ter certeza que ao invocar add (que vem de List) o objeto real que está sendo referenciado vai fazer o serviço.
Exemplo:

[code]public static void main( String[] args ) {
List a = new ArrayList();
List b = new LinkedList();
ArrayList c = new ArrayList();

// ok, a é do tipo List  (mas o objeto é do tipo ArrayList)
adicionaNaLista( a, "um" );

// ok, b é do tipo List (mas o objeto é do tipo LinkedList)
adicionaNaLista( b, "dois" );

// ok, c é do tipo ArrayList e funciona pois um ArrayList É UM List
adicionaNaLista( c, "três" );

}

public static void adicionaNaLista( List lista, String valor ) {
lista.add( valor ); // chamada polimórfica aqui!
}[/code]
[]'s

Leia uma explicação detalhada em: