Una interfaz en Java es similar a una clase, pero el cuerpo de una interfaz solo puede incluir métodos y
final
campos abstractos (constantes).
Recientemente, vi una pregunta, que se ve así
interface AnInterface {
public default void myMethod() {
System.out.println("D");
}
}
Según la definición de interfaz, solo se permiten métodos abstractos . ¿Por qué me permite compilar el código anterior? Cual es la default
palabra clave?
Por otro lado, cuando estaba tratando de escribir el código siguiente, dice modifier default not allowed here
default class MyClass{
}
en vez de
class MyClass {
}
¿Alguien puede decirme el propósito de la default
palabra clave? ¿Solo está permitido dentro de una interfaz? ¿En qué se diferencia de default
(sin modificador de acceso)?
Respuestas:
Es una característica nueva en Java 8 que permite
interface
proporcionar una implementación. Descrito en Java 8 JLS-13.5.6. Declaraciones del método de interfaz que dice (en parte)Lo nuevo en JDK 8 dice (en parte)
fuente
private
métodos.private
métodos no son realmente parte de la interfaz, pero pueden servir como métodos auxiliares para lasdefault
implementaciones o dentro de inicializadores constantes. Tenga en cuenta que ya existen en Java 8, ya que, cuando usa expresiones lambda dentro de las interfaces,private
se generan métodos sintéticos . Entonces, Java 9 le permite usar esa función para usos no sintéticos, no lambda también ...Se agregaron métodos predeterminados a Java 8 principalmente para admitir expresiones lambda. Los diseñadores (inteligentemente, en mi opinión) decidieron crear una sintaxis lambdas para crear implementaciones anónimas de una interfaz. Pero dado que las lambdas solo pueden implementar un solo método, estarían limitadas a interfaces con un solo método, lo que sería una restricción bastante severa. En su lugar, se agregaron métodos predeterminados para permitir el uso de interfaces más complejas.
Si necesita algo de convicción sobre la afirmación que
default
se introdujo debido a las lambdas, tenga en cuenta que la propuesta del hombre de paja del Proyecto Lambda, de Mark Reinhold, en 2009, menciona los 'Métodos de extensión' como una característica obligatoria que se agregará para admitir lambdas.Aquí hay un ejemplo que demuestra el concepto:
interface Operator { int operate(int n); default int inverse(int n) { return -operate(n); } } public int applyInverse(int n, Operator operator) { return operator.inverse(n); } applyInverse(3, n -> n * n + 7);
Muy artificial, me doy cuenta, pero debería ilustrar cómo
default
admite lambdas. Dado queinverse
es un valor predeterminado, una clase de implementación puede anularlo fácilmente si es necesario.fuente
Se introduce un nuevo concepto en Java 8 llamado métodos predeterminados. Los métodos predeterminados son aquellos que tienen alguna implementación predeterminada y ayudan a desarrollar las interfaces sin romper el código existente. Veamos un ejemplo:
public interface SimpleInterface { public void doSomeWork(); //A default method in the interface created using "default" keyword default public void doSomeOtherWork(){ System.out.println("DoSomeOtherWork implementation in the interface"); } } class SimpleInterfaceImpl implements SimpleInterface{ @Override public void doSomeWork() { System.out.println("Do Some Work implementation in the class"); } /* * Not required to override to provide an implementation * for doSomeOtherWork. */ public static void main(String[] args) { SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl(); simpObj.doSomeWork(); simpObj.doSomeOtherWork(); } }
y la salida es:
Implementación Do Some Work en la clase
Implementación DoSomeOtherWork en la interfaz
fuente
Algo que se pasó por alto en las otras respuestas fue su papel en las anotaciones. Ya en Java 1.5, la
default
palabra clave surgió como un medio para proporcionar un valor predeterminado para un campo de anotación.@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Processor { String value() default "AMD"; }
Su uso estaba sobrecargado con la introducción de Java 8 para permitir que uno defina un método predeterminado en las interfaces.
Algo más que se pasó por alto: la razón por la que la declaración
default class MyClass {}
no es válida se debe a la forma en que se declaran las clases . No hay ninguna disposición en el idioma que permita que esa palabra clave aparezca allí. Sin embargo , sí aparece para declaraciones de métodos de interfaz .fuente
La nueva característica de Java 8 ( Métodos predeterminados ) permite que una interfaz proporcione una implementación cuando está etiquetada con el
default
palabra clave.Por ejemplo:
interface Test { default double getAvg(int avg) { return avg; } } class Tester implements Test{ //compiles just fine }
Prueba de interfaz usa la palabra clave predeterminada que permite que la interfaz proporcione una implementación predeterminada del método sin la necesidad de implementar esos métodos en las clases que usan la interfaz.
Compatibilidad con versiones anteriores: Imagine que su interfaz está implementada por cientos de clases, modificar esa interfaz obligará a todos los usuarios a implementar el método recién agregado, aunque no es esencial para muchas otras clases que implementan su interfaz.
Hechos y restricciones:
1-Solo puede declararse dentro de una interfaz y no dentro de una clase o clase abstracta.
2-Debe aportar un cuerpo
3-No se asume que sea público o abstracto como otros métodos normales usados en una interfaz.
fuente
Los métodos predeterminados en una interfaz nos permiten agregar nuevas funcionalidades sin romper el código antiguo.
Antes de Java 8, si se agregaba un nuevo método a una interfaz, entonces todas las clases de implementación de esa interfaz estaban destinadas a anular ese nuevo método, incluso si no usaban la nueva funcionalidad.
Con Java 8, podemos agregar la implementación predeterminada para el nuevo método usando la
default
palabra clave antes de la implementación del método.Incluso con clases anónimas o interfaces funcionales, si vemos que algún código es reutilizable y no queremos definir la misma lógica en todas partes del código, podemos escribir implementaciones predeterminadas de esas y reutilizarlas.
Ejemplo
public interface YourInterface { public void doSomeWork(); //A default method in the interface created using "default" keyword default public void doSomeOtherWork(){ System.out.println("DoSomeOtherWork implementation in the interface"); } } class SimpleInterfaceImpl implements YourInterface{ /* * Not required to override to provide an implementation * for doSomeOtherWork. */ @Override public void doSomeWork() { System.out.println("Do Some Work implementation in the class"); } /* * Main method */ public static void main(String[] args) { SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl(); simpObj.doSomeWork(); simpObj.doSomeOtherWork(); } }
fuente
Se encuentra una muy buena explicación en los tutoriales de Java ™. , parte de la explicación es la siguiente:
Considere un ejemplo que involucra a fabricantes de automóviles controlados por computadora que publican interfaces estándar de la industria que describen qué métodos pueden invocarse para operar sus automóviles. ¿Qué pasa si esos fabricantes de automóviles controlados por computadora agregan nuevas funciones, como el vuelo, a sus automóviles? Estos fabricantes necesitarían especificar nuevos métodos para permitir que otras empresas (como los fabricantes de instrumentos de guía electrónica) adapten su software a los coches voladores. ¿Dónde declararían estos fabricantes de automóviles estos nuevos métodos relacionados con los vuelos? Si los agregan a sus interfaces originales, los programadores que hayan implementado esas interfaces tendrían que reescribir sus implementaciones. Si los agregan como métodos estáticos, los programadores los considerarían como métodos de utilidad, no como métodos básicos esenciales.
Los métodos predeterminados le permiten agregar nuevas funciones a las interfaces de sus bibliotecas y garantizar la compatibilidad binaria con el código escrito para versiones anteriores de esas interfaces.
fuente
Los métodos predeterminados le permiten agregar nuevas funciones a las interfaces de sus aplicaciones. También se puede utilizar para tener una herencia múltiple . Además de los métodos predeterminados, puede definir métodos estáticos en interfaces. Esto le facilita la organización de los métodos de ayuda.
fuente