¿Por qué se declaran las variables con su nombre de interfaz en Java?

Esta es una verdadera pregunta para principiantes (todavía estoy aprendiendo los conceptos básicos de Java).

Puedo (más o menos) entender por qué los métodos devolverían una Lista en lugar de una ArrayList , o por qué aceptarían un parámetro List en lugar de una ArrayList. Si no hace ninguna diferencia en el método (es decir, si no se requieren métodos especiales de ArrayList), esto haría que el método sea más flexible y más fácil de usar para las personas que llaman. Lo mismo ocurre con otros tipos de colecciones, como Establecer o Mapa.

Lo que no entiendo: parece ser una práctica común crear variables locales como esta:

List list = new ArrayList(); 

Si bien esta forma es menos frecuente:

 ArrayList list = new ArrayList(); 

¿Cuál es la ventaja aquí?

Todo lo que puedo ver es una desventaja menor: se debe agregar una línea de “importación” separada para java.util.List. Técnicamente, se puede usar “import java.util. *”, Pero tampoco lo veo con mucha frecuencia, probablemente porque algunas IDE agregan automáticamente las líneas de “importación”.

Cuando lees

 List list = new ArrayList(); 

usted tiene la idea de que todo lo que le importa es ser una List y pone menos énfasis en la implementación real. Además, se restringe a los miembros declarados por List y no a la implementación particular. No importa si sus datos se almacenan en una matriz lineal o en una estructura de datos sofisticada, siempre que se vea como una List .

Por otro lado, leer la segunda línea le da la idea de que al código le importa la variable ArrayList . Al escribir esto, está diciendo implícitamente (a los lectores futuros) que no debe cambiar ciegamente el tipo de objeto real porque el rest del código se basa en el hecho de que realmente es un ArrayList .

El uso de la interfaz le permite cambiar rápidamente la implementación subyacente de List / Map / Set / etc.

No se trata de guardar las pulsaciones de teclas, se trata de cambiar la implementación rápidamente. Idealmente, no debería exponer los métodos específicos subyacentes de la implementación y simplemente usar la interfaz requerida.

Sugeriría pensar en esto desde el otro lado. Por lo general, quiere una Lista o un Conjunto o cualquier otro tipo de Colección, y realmente no le importa cómo se implementa esto en su código. Por lo tanto, su código solo funciona con una lista y hacer lo que sea necesario (también redactado como “siempre codifica las interfaces”).

Cuando crea la Lista, debe decidir qué implementación real desea. Para la mayoría de los propósitos, ArrayList es “lo suficientemente bueno”, pero a su código realmente no le importa. Al apegarse al uso de la interfaz, usted transmite esto al futuro lector.

Por ejemplo, tengo el hábito de tener un código de depuración en mi método principal, que vierte las propiedades del sistema a System.out – por lo general, es mucho mejor que se clasifiquen. La forma más fácil es simplemente dejar “Map map = new TreeMap (properties);” y luego iterar a través de ellos, ya que TreeMap devuelve las claves ordenadas.

Cuando aprenda más sobre Java, también verá que las interfaces son muy útiles en las pruebas y burlas, ya que puede crear objetos con un comportamiento especificado en tiempo de ejecución que se ajuste a una interfaz determinada. Se puede ver un ejemplo avanzado (pero simple) en http://www.exampledepot.com/egs/java.lang.reflect/ProxyClass.html

si luego desea cambiar la implementación de la lista y usar, por ejemplo, LinkedList (quizás para un mejor rendimiento), no tiene que cambiar todo el código (y API si es su biblioteca). si el orden no importa, debe devolver la Colección para poder cambiarla fácilmente a Establecer si necesita elementos para ordenar.

La mejor explicación que puedo encontrar (porque no programo en Java con tanta frecuencia como en otros lenguajes) es que hace que sea más fácil cambiar el tipo de lista de “back-end” mientras se mantiene el mismo código / interfaz todo lo demás depender de. Si primero lo declaras como un tipo más específico, luego decides que quieres un tipo diferente … si algo sucede con el uso de un método específico de ArrayList, eso es trabajo extra.

Por supuesto, si realmente necesita un comportamiento específico de ArrayList, debería elegir el tipo de variable específico.

El punto es identificar el comportamiento que desea / necesita y luego usar la interfaz que proporciona ese comportamiento. El es el tipo para tu variable. Luego, use la implementación que satisfaga sus otras necesidades: eficiencia, etc. Esto es lo que crea con “nuevo”. Esta dualidad es una de las principales ideas detrás de OOD. El problema no es particularmente significativo cuando se trata de variables locales, pero rara vez duele seguir buenas prácticas de encoding todo el tiempo.

Básicamente, esto proviene de personas que tienen que ejecutar grandes proyectos, posiblemente por otros motivos: lo escuchas todo el tiempo. Por qué, en realidad no sé. Si necesita una lista de matriz, o Hash Map o Hash Set o cualquier otra cosa, no veo el sentido de eliminar los métodos al convertirlos a una interfaz.

Digamos, por ejemplo, recientemente aprendí cómo usar e implementar HashSet como una estructura de datos de principio. Supongamos, por alguna razón, que fui a trabajar en un equipo. ¿No necesitaría esa persona saber que los datos estaban basados ​​en enfoques hash en lugar de estar ordenados por alguna base? El enfoque de back-end observado por Twisol funciona en C / C ++, donde puedes exponer los encabezados y vender una biblioteca. Si alguien sabe cómo hacerlo en Java, me imagino que usaría JNI, y en ese momento me parece más sencillo. para usar C / C ++ donde puede exponer los encabezados y comstackr libs utilizando las herramientas establecidas para ese fin.

Para cuando puedas encontrar a alguien que pueda instalar un archivo jar en el directorio de extensiones, me parecería que la entidad podría estar a solo unos pasos de distancia. Dejé varias librerías de cifrado en el directorio de extensiones, que era útil, pero realmente me gustaría. para ver una base clara y concisa dilucidada. Me imagino que lo hacen todo el tiempo.

En este punto, me parece una ofuscación clásica, pero cuidado: tienes que progtwigr algo antes de que el problema sea importante.