¿Cuál es el método predeterminado?
Después de que se libera Java 8, se pueden agregar nuevos métodos a la interfaz, pero la interfaz aún puede ser compatible con su clase de implementación. Esto es muy importante porque la biblioteca de clases que desarrolla puede ser ampliamente utilizada por múltiples desarrolladores. Antes de Java 8, después de que se lanzara una interfaz en la biblioteca de clases, si se agregó un nuevo método a la interfaz, aquellas aplicaciones que implementan esta interfaz estarían en riesgo de bloquear el uso de la nueva versión de la interfaz.
Con Java 8, ¿no hay tal peligro? La respuesta es no.
Agregar un método predeterminado a una interfaz puede hacer que algunas clases de implementación no estén disponibles.
Primero, veamos los detalles del método predeterminado.
En Java 8, se pueden implementar métodos en las interfaces (los métodos estáticos en Java 8 también se pueden implementar en interfaces, pero este es otro tema). El método implementado en la interfaz se llama el método predeterminado, que se identifica por la palabra clave predeterminada como un modificador. Cuando una clase implementa una interfaz, puede implementar métodos que se han implementado en la interfaz, pero esto no es necesario. Esta clase heredará el método predeterminado. Es por eso que cuando cambia la interfaz, la clase de implementación no necesita cambiarse.
¿Qué pasa con el momento de heredar más?
Las cosas se complican cuando una clase implementa más de una (por ejemplo, dos) interfaces y estas interfaces tienen el mismo método predeterminado. ¿Qué método predeterminado hereda la clase? ¡Ninguno de ellos lo es! En este caso, la clase debe implementar el método predeterminado (solo) por sí solo (directamente o heredar las clases de nivel superior en el árbol).
Lo mismo es cierto cuando una interfaz implementa el método predeterminado y la otra interfaz declara el método predeterminado como resumen. Java 8 intenta evitar cosas poco claras y mantenerlo riguroso. Si se declara un método en múltiples interfaces, entonces cualquier implementación predeterminada no se heredará y obtendrá un error de tiempo de compilación.
Sin embargo, si ha compilado su clase, no habrá errores de tiempo de compilación. En este punto, Java 8 es inconsistente. Tiene sus propias razones, por varias razones. No quiero explicarlo en detalle o discutirlo en profundidad aquí (porque: la versión se ha lanzado y la discusión ha sido demasiado larga, y esta plataforma nunca lo ha discutido así).
La clase puede ejecutarse normalmente en el caso anterior. Sin embargo, no se puede volver a compilar con interfaces modificadas, pero aún puede ejecutarse con interfaces viejas. Próximo
Cuando ambas interfaces proporcionan implementaciones predeterminadas al mismo método, no se puede llamar a este método a menos que la clase de implementación también implementa el método predeterminado (ya sea directamente lo implementa o hereda la clase de nivel superior en el árbol para la implementación).
Sin embargo, esta clase es compatible. Se puede cargar con nuevas interfaces, o incluso ejecutar, siempre que no llame a un método que tenga una implementación predeterminada en ambas interfaces.
Código de ejemplo
Para demostrar el ejemplo anterior, creé un directorio de prueba para C.Java, que tiene 3 subdirectorios a continuación, que se utilizan para almacenar i1.java e i2.java. El directorio de prueba contiene el código fuente de C.Java de la clase C. El directorio base contiene la interfaz a la versión que se puede compilar y ejecutar. I1 contiene el método m () implementado por defecto, e I2 no contiene ningún método.
La clase de implementación contiene el método principal, por lo que podemos ejecutarlo en la prueba. Verificará si hay parámetros de línea de comandos, para que podamos ejecutar fácilmente las pruebas que llamen a M () y no llamar a M ().
Public Class C implementos i1, i2 {public static void main (String [] args) {c c = new C (); if (args.length == 0) {cm (); }}} interfaz pública i1 {predeterminado void m () {System.out.println ("Hello Interface 1"); }} interfaz pública i2 {}Use la siguiente línea de comando para compilar y ejecutar:
javac -cp .: base c.javajava -cp .: interfaz de chello base 1
El directorio compatible contiene la interfaz i2 con el método abstracto m () y la interfaz I1 no modificada.
interfaz pública i2 {void m ();}Esto no se puede usar para compilar la clase C:
Javac -Cp .: Compatible C.Javac.Java:1: Error: C no es abstracto y no anula el método abstracto m () en I2Public Clase C Implementos I1, I2 { ^ 1 ErrorEl mensaje de error es muy preciso. Debido a que tenemos el C.Class obtenido de la compilación anterior, si compilamos la interfaz en el directorio compatible, aún obtendremos dos interfaces que pueden ejecutar la clase de implementación:
Javac Compatible/i*.javajava -cp .: Interfaz de Chello compatible 1
El tercer directorio llamado incorrecto, y la interfaz i2 contenida también define el método m ():
interfaz pública i2 {predeterminado void m () {System.out.println ("Hello Interface 2"); }}Nunca debemos cansarnos de compilarlo. Aunque el método m () se define dos veces, la clase de implementación aún puede ejecutarse siempre que no llame al método que se ha definido varias veces, pero siempre que llamemos el método m (), fallará de inmediato. Aquí están los parámetros de la línea de comando que utilizamos:
javac mal/*. javajava -cp.: incorrecta c excepción en hilo "main" java.lang.incompatibleClassChangeError: Métodos predeterminados conflictivos: i1.m i2.m at cm (c.java) en C.Main (C.Java:5) Java -Cp.: incorrecto C X
en conclusión
Cuando porte la biblioteca de clases que agrega la implementación predeterminada a la interfaz al entorno Java 8, generalmente no habrá ningún problema. Al menos esto es lo que piensan los desarrolladores de la biblioteca de clases Java8 al agregar métodos predeterminados a las clases de recopilación. Las aplicaciones que usan su biblioteca de clases aún dependen de la biblioteca de clases de Java7 sin el método predeterminado. Al usar y modificar varias bibliotecas de clase diferentes, hay una pequeña posibilidad de conflicto. ¿Cómo puedo evitarlo?
Diseñe su biblioteca de clases como antes. No lo tome a la ligera cuando pueda confiar en el método predeterminado. No lo use como absolutamente necesario. Elija el nombre del método sabiamente para evitar conflictos con otras interfaces. Aprenderemos cómo usar esta función para el desarrollo en la programación Java.
Resumir
Lo anterior es todo el contenido de este artículo. Espero que el contenido de este artículo tenga cierto valor de referencia para el estudio o el trabajo de todos. Si tiene alguna pregunta, puede dejar un mensaje para comunicarse. Gracias por su apoyo a Wulin.com.