Polimorfismo: ¿Por qué utilizar "List list = new ArrayList" en lugar de "ArrayList list = new ArrayList"? [duplicar]

Resuelto hqt asked hace 12 años • 8 respuestas

Posible duplicado:
¿Por qué debería preferirse la interfaz para una clase Java?

¿Cuándo debo usar?

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

ArrayListhereda de List, por lo que si algunas características de ArrayListno están en List, entonces habré perdido algunas de las características de ArrayList, ¿verdad? ¿Y el compilador notará un error al intentar acceder a estos métodos?

hqt avatar Mar 24 '12 22:03 hqt
Aceptado

La razón principal por la que haría esto es para desacoplar su código de una implementación específica de la interfaz. Cuando escribes tu código de esta manera:

List list = new ArrayList();  

el resto de su código solo sabe que los datos son de tipo List, lo cual es preferible porque le permite cambiar entre diferentes implementaciones de la Listinterfaz con facilidad.

Por ejemplo, digamos que estaba escribiendo una biblioteca de terceros bastante grande y que decidió implementar el núcleo de su biblioteca con un archivo LinkedList. Si su biblioteca depende en gran medida del acceso a elementos de estas listas, eventualmente descubrirá que ha tomado una mala decisión de diseño; Te darás cuenta de que deberías haber usado un ArrayList(que proporciona un tiempo de acceso O(1)) en lugar de un LinkedList(que proporciona un tiempo de acceso O(n)). Suponiendo que haya estado programando en una interfaz, realizar dicho cambio es fácil. Simplemente cambiarías la instancia de Listfrom,

List list = new LinkedList();

a

List list = new ArrayList();  

y sabes que esto funcionará porque has escrito tu código para seguir el contrato proporcionado por la Listinterfaz.

Por otro lado, si hubiera implementado el núcleo de su biblioteca usando LinkedList list = new LinkedList(), realizar dicho cambio no sería tan fácil, ya que no hay garantía de que el resto de su código no utilice métodos específicos de la LinkedListclase.

Considerándolo todo, la elección es simplemente una cuestión de diseño... pero este tipo de diseño es muy importante (especialmente cuando se trabaja en proyectos grandes), ya que le permitirá realizar cambios específicos de la implementación más adelante sin romper el código existente.

Alex Lockwood avatar Mar 24 '2012 15:03 Alex Lockwood

Esto se llama programación para interfaz. Esto será útil en caso de que desee pasar a alguna otra implementación de List en el futuro. Si desea incluir algunos métodos, ArrayListdeberá programar la implementación ArrayList a = new ArrayList().

tsatiz avatar Mar 24 '2012 15:03 tsatiz

Esto también resulta útil al exponer una interfaz pública. Si tienes un método como este,

public ArrayList getList();

Entonces decides cambiarlo a,

public LinkedList getList();

Cualquiera que lo estuviera haciendo ArrayList list = yourClass.getList()deberá cambiar su código. Por otro lado, si lo haces,

public List getList();

Cambiar la implementación no cambia nada para los usuarios de su API.

Brendan Long avatar Mar 24 '2012 18:03 Brendan Long

Creo que la respuesta de @tsatiz es mayoritariamente correcta (programación en una interfaz en lugar de una implementación). Sin embargo, al programar la interfaz no perderá ninguna funcionalidad . Dejame explicar.

Si declara su variable como, List<type> list = new ArrayList<type>en realidad no pierde ninguna funcionalidad de ArrayList. Todo lo que necesitas hacer es bajar tu listnivel a ArrayList. He aquí un ejemplo:

List<String> list = new ArrayList<String>();
((ArrayList<String>) list).ensureCapacity(19);

En última instancia, creo que tsatiz tiene razón, ya que una vez que envías a ArrayList ya no estás codificando en una interfaz. Sin embargo, sigue siendo una buena práctica codificar inicialmente en una interfaz y, si luego es necesario, codificar en una implementación si es necesario.

¡Espero que ayude!

SecondSun24 avatar Mar 27 '2012 18:03 SecondSun24