java - method - ¿Cuál es la implementación "predeterminada" del método definido en una interfaz?
static interface c# (3)
Esos métodos se llaman métodos predeterminados. El método predeterminado o el método Defender es una de las funciones recientemente agregadas en Java 8.
Se usarán para permitir que un método de interfaz proporcione una implementación utilizada como predeterminada en caso de que una clase concreta no proporcione una implementación para ese método.
Entonces, si tienes una interfaz, con un método predeterminado:
public interface Hello {
default void sayHello() {
System.out.println("Hello");
}
}
La siguiente clase es perfectamente válida:
public class HelloImpl implements Hello {
}
Si crea una instancia de HelloImpl
:
Hello hello = new HelloImpl();
hello.sayHello(); // This will invoke the default method in interface
Enlaces útiles:
En la interfaz de colección, encontré un método llamado removeIf()
que contiene su implementación.
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
if (filter.test(each.next())) {
each.remove();
removed = true;
}
}
return removed;
}
Quiero saber si hay alguna forma de definir el cuerpo del método en una interfaz.
¿Cuál es la palabra clave default
y cómo funciona?
Hice un poco de investigación y encontré lo siguiente. Espero que esto ayude.
Problema existente
Los métodos de interfaz normales se declaran como abstractos y se deben definir en la clase que implementa la interfaz. Esto ''carga'' al implementador de la clase con la responsabilidad de implementar cada método declarado. Más importante aún, esto también significa que la extensión de una interfaz no es posible después de ''publicación''. De lo contrario, todos los implementadores tendrían que adaptar su implementación, rompiendo la compatibilidad con versiones anteriores de origen y binario.
Solución adoptada en Java 8
Para hacer frente a estos problemas, una de las nuevas características de JDK 8 es la posibilidad de ampliar las interfaces existentes con métodos predeterminados. Los métodos predeterminados no solo se declaran, sino que también se definen en la interfaz.
Puntos importantes a tener en cuenta
- Los implementadores pueden elegir no implementar métodos predeterminados en la implementación de la clase.
- Los implementadores aún pueden anular los métodos predeterminados, como los métodos de clase normales no finales pueden anularse en las subclases.
- Las clases abstractas pueden incluso (re) declarar los métodos por defecto como abstract, forzando a las subclases a volver a implementar el método (a veces llamado ''re-abstracción'').
Java 8 introduce la nueva característica "Método predeterminado" o (métodos Defender), que permite al desarrollador agregar nuevos métodos a las interfaces sin romper la implementación existente de estas. Proporciona flexibilidad para permitir la implementación de la definición de interfaz que se utilizará como predeterminada en la situación en que una clase concreta no proporcione una implementación para ese método.
public interface A {
default void foo(){
System.out.println("Calling A.foo()");
}
}
public class ClassAB implements A {
}
Hay una pregunta común que las personas hacen sobre los métodos predeterminados cuando oyen hablar de la nueva función por primera vez:
¿Qué pasa si la clase implementa dos interfaces y ambas interfaces definen un método predeterminado con la misma firma?
Ejemplo para ilustrar esta situación:
public interface A {
default void foo(){
System.out.println("Calling A.foo()");
}
}
public interface B {
default void foo(){
System.out.println("Calling B.foo()");
}
}
public class ClassAB implements A, B {
}
Este código no se puede compilar con el siguiente resultado:
java: class Clazz inherits unrelated defaults for foo() from types A and B
Para solucionarlo, en Clazz, tenemos que resolverlo manualmente anulando el método en conflicto:
public class Clazz implements A, B {
public void foo(){}
}
Pero, ¿qué ocurre si queremos llamar a la implementación predeterminada del método foo () desde la interfaz A en lugar de implementar la nuestra propia?
Es posible hacer referencia a A # foo () de la siguiente manera:
public class Clazz implements A, B {
public void foo(){
A.super.foo();
}
}