Se le conoce como interface funcional a toda aquella interface que tenga solamente un método abstracto, es decir puede implementar uno o más métodos default, pero deberá tener forzosamente un único método abstracto. Si no te queda claro que es un método abstracto en una interface, es un método sin implementar.
Las interfaces funcionales es un nuevo concepto que fue agregado a partir de la versión 8 de Java y cobran su importancia al utilizar expresiones lambda (λ).
Ejemplo de interfaces funcionales:
A continuación, veremos ejemplos de dos interfaces funcionales válidas:
package com.osb.functionalinterface; /** * @author Oscar Blancarte */ public interface IStrategy { public String sayHelloTo(String name); }
En esta interface, definimos un método que manda un saludo a la persona que le pasamos como parámetro, pero todavía no está definido el cuerpo del método.
package com.osb.functionalinterface; /** * @author Oscar Blancarte */ public interface IStrategy { public String sayHelloTo(String name); public default String sayHelloWord(){ return "Hello word"; } }
Esta segunda interface, también es una interface funcional, ya que solo tiene un método abstracto.
Otra forma de asegurarnos de que estamos definiendo correctamente una interface funcional, es anotarla con @FunctionalInterface , ya que al anotarla el IDE automáticamente nos arrojara un error si no cumplimos con las reglas de una interface funcional. Sin embargo, es importante resaltar que en tiempo de ejecución no nos dará un comportamiento diferente, puesto que es utilizada para prevenir errores al momento de definir las interfaces. Veamos cómo quedaría la clase anterior con esta anotación:
package com.osb.functionalinterface; /** * @author Oscar Blancarte */ @FunctionalInterface public interface IStrategy { public String sayHelloTo(String name); public default String sayHelloWord(){ return "Hello word"; } }
Interfaces funcionales con expresiones lambda:
Ya con la teoría, veamos cómo podría utilizar la clase IStrategy mediante expresiones lambda:
package com.osb.functionalinterface; /** * @author Oscar Blancarte */ public class Main { public static void main(String[] args) { IStrategy strategy = (name) -> "Hello " + name; System.out.println(strategy.sayHelloTo("Oscar Blancarte")); System.out.println(strategy.sayHelloWord()); } }
Veamos como en la línea 8 definimos una expresión lamba en donde concatena Hello con el nombre de la persona que es pasada como parámetro, luego esta expresión es asignada a la variable a la variable strategy , la cual es de tipo IStrategy . Luego de esto mandamos llamar al método sayHelloTo el cual nos regresa el saludo para Oscar Blancarte, seguido en la línea 11 llamamos al método sayHelloWord , el cual manda un Hello Word.
Como vemos la expresión lambda siempre se asigna al método abstracto, por este motivo el método sayHelloTo es implementado con el cuerpo de la expresión lamba, mientras que el método sayHelloWord continua con la misma implementación que viene desde la interface.
Observemos la imagen anterior, cuando una expresión lambda es asignada a una interface, está siempre implementará el método abstracto, es por esta razón por la que solo puede existir un método abstracto y muchos defaults.
Finalmente, el resultado de la ejecución es el siguiente:
Hello Oscar Blancarte Hello word
Hola buenas, dices que las interfaces funcionales son aquellas que al menos tienen un metodo abstracto, pero el método que pones no es abstracto
Hola Jorge, en una interfaz, los métodos sin cuerpo son abstractos, aun que no tengan la palabra reservada abstract, de igual forma te invitamos a ver nuestro curso de Lambdas + Strams,
Excelente explicación, breve y entendible.
Gracias Mauricio
Estoy tomando un curso a parte, investigando más encuentro este publicación, me aclara un par de cosas y me ayuda a comprender más.
Gracias.