Desde versiones anteriores conoces las interfaces SAM (Single Abstract Method interfaces).
Es decir, interfaces que tienen un solo método abstracto; ejemplo de ellas encontramos a java.lang.Runnable
public interface Runnable {
public abstract void run();
}
Usualmente utilizamos este tipo de interfaz de forma anónima
public class ServiceExample {
public void doWork() {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Running and working ...");
}
}).start();
}
}
Java 8 mantiene estas SAM interfaces pero las llama Functional Interfaces. Creando además una anotación específica @FunctionalInterface que le dará la instrucción al compilador para que verifique que la interfaz anotada cumple con los requisitos de una interfaz funcional.
Requisitos de una interfaz funcional.
Las interfaces funcionales tienen la característica de contar con un solo método abstracto.
También pueden contar con más de un método siempre y cuando estos métodos sobrescriban métodos de la clase Object o sean métodos predeterminados, default.
Los métodos predeterminados (marcados con “default”) no son abstractos, por lo cual una interfaz funcional puede definir varios métodos predeterminados.
Por ejemplo, veamos esta interfaz ‘MyInterface’. Contiene un método funcional “doSomething”, dos métodos de la clase Object ‘toString’ y ‘equals’ y un método default ‘doSomething2’
@FunctionalInterface
public interface MyInterface {
public void doSomething();
default public void doSomething2() { System.out.print("Hi");};
public String toString();
public boolean equals(Object o);
}
Si cometemos el error de intentar agregar dos métodos a nuestra interfaz funcional recibiremos este error “multiple non-overriding abstract methods found”
@FunctionalInterface
public interface MyInterface {
public void doSomething(); // metodo funcional
default public void doSomething2() { System.out.print("Hi");}; // metodo default
public void doSomethingWrong(); // otro metodo funcional. mal!
public String toString(); // sobreescribe
public boolean equals(Object o); // sobreescribe
}
Bien y todo este rollo de interfaces funcionales ¿para que? Principalmente para trabajar con expresiones Lambda, que veremos en otro post.