一、函数式接口
首先是一个接口,然后就是在这个接口里面只能有一个抽象方法。这种类型的接口也称为SAM接口,即Single Abstract Method interfaces。
即只有一个抽象方法的接口,称为函数式接口,可以用@FunctionalInterface修饰。
这里需要注意的是:未使用 @FunctionalInterfaces注解的接口未必就不是函数式接口,一个接口是不是函数式接口的条件只有一条,即接口中只有一个抽象方法的接口(Object类中的方法不算)。
以下接口中虽然有两个方法,但因hashCode()是Object类中的方法,因此该接口也是函数式接口
@FunctionalInterface
public interface FuncInterface {
void doSomething();
int hashCode(); // Object类中的方法
}
@FunctionalInterface注解
Java 8为函数式接口引入了一个新注解@FunctionalInterface,主要用于编译级错误检查,加上该注解,当你写的接口不符合函数式接口定义的时候,编译器会报错。所以使@FunctionalInterface注解修饰了的接口就一定是函数式接口
Tips:加不加@FunctionalInterface对于接口是不是函数式接口没有影响,该注解知识提醒编译器去检查该接口是否仅包含一个抽象方法
函数型接口只有一个抽象方法的接口,但是函数型接口可以包含以下方法
java四大内置函数(函数式接口)
Consumer<T> 消费型接口(无返回值,有去无回)
void accept(T t);
Supplier<T> 供给型接口
T get();
Function<T,R> 函数型接口
R apply(T t);
Predicate<T> 断言型接口
boolean test(T t);
二、接口默认方法
为了提高代码的可重用性,接口的默认方法有助于在扩展系统功能的同时,不对现有的继承关系及类库产生很大的影响。
默认方法语法格式如下:
interface TestFace {
default 返回类型 methodName(参数列表) {
// 实现体
}
}
多个默认方法
一个接口有默认方法,考虑这样的情况,一个类实现了多个接口,且这些接口有相同的默认方法,以下实例说明了这种情况的解决方法:
public interface Vehicle {
default void print(){
System.out.println("我是一辆车!");
}
}
public interface FourWheeler {
default void print(){
System.out.println("我是一辆四轮车!");
}
}
解决方法:实现方法使用 super 来调用指定接口的默认方法:
public class Car implements Vehicle, FourWheeler {
@Override
public void print(){
Vehicle.super.print();
FourWheeler.super.print();
}
}
静态默认方法
函数式接口里是可以包含静态方法,因为静态方法不能是抽象方法,是一个已经实现了的方法,所以是符合函数式接口的定义的;
例如:
public interface Vehicle {
default void print() {
System.out.println("我是一辆车!");
}
// 静态方法
static void blowHorn() {
System.out.println("按喇叭!!!");
}
// 使用类名调用
static void main(String[] args) {
Vehicle.blowHorn();
}
}
同时函数式接口里是可以包含默认方法,因为默认方法不是抽象方法,其有一个默认实现,所以是符合函数式接口的定义的;
@FunctionalInterface
interface GreetingService {
void sayMessage(String message);
default void doSomeWork(){
System.out.println("do someThing");
}
}