一. 函数式接口
如果一个接口定义唯一一个抽象方法,那么这个接口就可以成为函数式接口,如 Runnable,Callable 接口。
可以在函数式接口前加一个 @FunctionalInterface注解,非必须。在接口中添加了@FunctionalInterface,只允许有一个抽象方法,否则编译器也报错。Java8 中 Runnable 接口就是一个函数式接口,如下:
-
@FunctionalInterface
-
public interface Runnable {
-
-
-
-
-
-
-
-
-
-
-
-
public abstract void run();
-
}
像Runnable,Callable等有且只有一个抽象方法的接口,一般称为单一抽象方法接口,我们平常使用它的时候,比较习惯于使用一个内部类,这至少也要几行的代码,如下:
-
public class AnonymousInnerClassTest {
-
public static void main(String[] args) {
-
new Thread(new Runnable() {
-
@Override
-
public void run() {
-
System.out.println("A thread created and running ...");
-
}
-
}).start();
-
}
-
}
如果我们声明为函数式接口,再结合Lambda表达式,那么一行代码就可以搞定,比较方便。如下代码:
-
-
-
-
-
-
public class SimpleFunInterfaceTest {
-
public static void main(String[] args) {
-
carryOutWork(new SimpleFuncInterface() {
-
@Override
-
public void doWork() {
-
System.out.println("Do work in SimpleFun impl...");
-
}
-
});
-
-
carryOutWork(() -> System.out.println("Do work in lambda exp impl..."));
-
}
-
public static void carryOutWork(SimpleFuncInterface sfi){
-
sfi.doWork();
-
}
-
}
输出为:
-
Do work in SimpleFun impl...
-
Do work in lambda exp impl...
当然,一个接口也可以继承另外一个函数式接口,只要它不再声明抽象方法(可以使用默认方法),那么它也是一个函数式接口。
例如:
-
@FunctionalInterface
-
public interface ComplexFunctionalInterface extends SimpleFuncInterface {
-
default public void doSomeWork(){
-
System.out.println("Doing some work in interface impl...");
-
}
-
default public void doSomeOtherWork(){
-
System.out.println("Doing some other work in interface impl...");
-
}
-
}
总结:好处在哪里?
结合Lambda表达式,比之前更加的简便。
二. 接口默认方法
Java8 可以在 interface 中有方法的实现,也称为默认方法。那么 interface 中 有了方法的实现,也就是说,可以实现多继承,(当然之前利用一些方法也可以实现多继承,但是Java 一直不提倡多继承)。
那么为什么现在加入了默认方法实现多继承呢?因为 interface 太过依赖他们的实现类了,要往 interface中加入一个方法就必须修改所有的实现类。那么Java8 中加入一些特性可能需要修改一些核心类,但是很多核心类不仅仅JDK中实现,很多第三方库中也会有实现,那么一改动可能就会出现兼容性问题。那么默认方法就可以很好的处理这个问题。
代码示例:
-
interface ITest {
-
public default void sayHello(){
-
System.out.println("Hello");
-
}
-
}
-
public class Test implements ITest{
-
public static void main(String[] args) {
-
new Test().sayHello();
-
}
-
}
注意,需要加一个 default。
参考: