Antes de Java 8, solo se pueden escribir métodos abstractos en las interfaces, pero no se pueden escribir métodos de implementación.
Java 8 puede tener métodos para implementar, puede agregar métodos predeterminados y métodos estáticos a las interfaces
El método predeterminado está default
decorado, que solo se puede usar en la interfaz, el método estático está static
decorado y puede haber varios métodos predeterminados y estáticos en la interfaz al mismo tiempo.
Por qué usar métodos predeterminados de interfaz
Tomemos un ejemplo muy realista:
Nuestra interfaz se escribió hace mucho tiempo y, más tarde, debido a varios problemas comerciales, es inevitable modificar la interfaz.
Antes de Java 8, por ejemplo, si desea agregar un método abstracto a una interfaz, todas las clases de implementación de la interfaz deben implementar este método; de lo contrario, habrá un error de compilación.
Y algunas clases de implementación no necesitan implementar este método en absoluto y se ven obligadas a escribir una implementación vacía, y los cambios serán muy grandes.
Por lo tanto, el método predeterminado de la interfaz es para resolver este problema. Siempre que se agregue un método predeterminado a una interfaz, todas las clases de implementación se heredarán automáticamente, y no es necesario cambiar ninguna clase de implementación, y no lo hará. afectar el negocio;
Además, los métodos predeterminados de la interfaz pueden ser anulados por las clases de implementación de la interfaz.
¿Por qué tener métodos estáticos de interfaz?
Los métodos estáticos de interfaz son similares a los métodos predeterminados, excepto que las clases de implementación de interfaz no pueden anular los métodos estáticos de interfaz.
Los métodos estáticos de la interfaz solo se pueden llamar directamente a través de .donde se encuentra el método estático 接口名
. 静态方法名
Problema de conflicto de herencia múltiple del método predeterminado de la interfaz
Debido a que los métodos predeterminados de la interfaz se pueden heredar y anular, si varias interfaces heredadas tienen el mismo método predeterminado, existe un problema de conflicto.
conflicto uno
interfaz Gente { predeterminado void comer() { System.out.println("La gente come."); } } interfaz Hombre { predeterminado void comer() { System.out.println("El hombre come."); } } // Boy hereda People y Man al mismo tiempo. En este momento, el editor de IDEA informará una interfaz de error Boy extends People, Man { } //Este es el problema de conflicto causado por la herencia múltiple de interfaces. Boy no sabe a quién heredar. //Esto es Obviamente, también es un problema, IDEA también le indicará que debe reescribir este método para resolver el problema: interfaz Boy extends People, Man { @Override default void eat() { People.super.eat( ); //También puede llamar directamente en el método Llamar al método predeterminado de la interfaz principal especificada Man.super.eat(); //En el método, también puede llamar directamente al método predeterminado de la interfaz principal especificada System.out .println("El niño come."); } }
Pruébalo con la clase de implementación.
class Student implements Boy { public static void main(String[] args) { Student student = new Student(); student.eat(); } } //resultado //La gente come. // Los hombres comen. //El niño come.
conflicto dos
Cambiemos la forma de escribir, Man
heredar People
y luego Man
anular People
el método predeterminado en
En este punto, el editor no informa de ningún error y People
el método predeterminado aparece atenuado, lo que indica que no se utiliza.
Ejecute el ejemplo anterior nuevamente y genere:
interfaz Gente { predeterminado void comer() { System.out.println("La gente come."); } } interfaz Hombre extiende Gente{ predeterminado void comer() { System.out.println("El hombre come."); } } interfaz Chico extiende Gente, Hombre { } //resultado //El hombre come
Debido Man
a la herencia People
, Man
se restablece el método predeterminado. Obviamente, en este momento, Boy
sabemos de quién es el método predeterminado que heredamos.
Tenga en cuenta que en este momento, si usa People
el método super
de llamar a la clase principal, eat
se informará un error porque no se puede llamar.
interfaz Chico extiende Gente, Hombre { @Override default void comer() { Gente.super.comer(); //Las personas reportan un error System.out.println("Boy come"); } }
conflicto tres
Agregue un nuevo método a la interfaz Man
: say
y luego Boy
agregue un método predeterminado a la interfaz: say
.
interface Man extiende People{ default void eat() { System.out.println("Man eats."); } void say(); //IDEA indica que el método say está atenuado y no se usa }
En este momento, Man
el método abstracto en realidad se ignora y IDEA
se le solicita que no se utilice. Obviamente, este es el método predeterminado que tiene prioridad sobre el método abstracto.
Resumir
Presenta métodos predeterminados y métodos estáticos en Java 8 , así como soluciones para métodos predeterminados en conflicto.
Si en el futuro se dice que la interfaz no puede escribir el método de implementación, será demasiado OUT
.