就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口,总体有点像匿名类
该注解可加可不加,它是函数式接口语法检查注解的,当然最好是加上,毕竟你加上之后,代码的规范和可读性明显提高了.
通常我们写一个接口大致如下:
public interface Animal {
void eat();
void say();
void run();
}
实现如下:
/**
* 实现类 :Dog, 子类要全部实现父接口的全部抽象方法
*/
public class Dog implements Animal {
@Override
public void eat() {
System.out.println("Dog eat");
}
@Override
public void say() {
System.out.println("Dog say");
}
@Override
public void run() {
System.out.println("Dog run");
}
}
应用如下:
@SpringBootTest
class DemoApplicationTests {
@Test
public void testFunctionInterface(){
Animal animal = new Dog();
animal.say();
animal.run();
animal.eat();
}
}
输出:
Dog say
Dog run
Dog eat
按照上面函数式接口的定义:接口中我们只保留一个抽象方法,
场景如下:
/**
* 只有一个抽象方法eat所以就满足是个函数式接口
*/
public interface Animal {
void eat();
/**
* 默认方法:子类可以也可以继承或者重写,
*/
default void say() {
System.out.println("Animal say");
};
/**
* 子类不可继承,接口直接调用
*/
static void run() {
System.out.println("Animal run");
};
}
/**
* 实现类Cat
*/
public class Cat implements Animal {
@Override
public void eat() {
System.out.println("Cat eat");
}
}
应用:
@SpringBootTest
class DemoApplicationTests {
@Test
public void testFunctionInterface(){
/**
* 函数式接口应用场景一
*/
// 直接调用接口中的静态方法
Animal.run();
// 相当于定义了Animal的唯一的一个抽象方法(eat)中的实现
Animal animal = () -> System.out.println("Lambda表达式实现的eat");
animal.eat();
// 执行默认方法
animal.say();
/**
* 函数式接口应用场景二
*/
Animal cat = new Cat();
// 执行子类重写的say方法
cat.say();
// 子类常规实现父接口中的eat方法
cat.eat();
/**
* 函数式接口应用场景三
*/
fead(() -> System.out.println("fead方法入参"));
}
public void fead(Animal animal) {
// 调用函数式接口中的抽象方法
animal.eat();
}
}
输出结果:
Animal run
Lambda表达式实现的eat
Animal say
Animal say
Cat eat
fead方法入参
函数式接口应用场景二和三中, 其实我们可以看出,那个Lambda表达式其实就相当于一个方法的方法体,也就是说是一个方法的实现, 这也是为什么函数式接口中要求只能有一个抽象方法,这样的话, 无论是 () -> System.out.println(“Lambda表达式实现的eat”)还是 () -> System.out.println(“fead方法入参”) 都相当于那个方法的实现,相当于冥冥中就创建了一个函数式接口的匿名实现类.
在包java.util.function下面有很多函数式接口, 函数式接口使用的最典型最广泛的地方也就是java8的Lambda表达式,可以详细看一下Lambda表达式的入参类型就知道了.