一. 函数式接口
如果一个接口定义唯一一个抽象方法,那么这个接口就可以成为函数式接口,如 Runnable,Callable 接口。
可以在函数式接口前加一个 @FunctionalInterface注解,非必须。在接口中添加了@FunctionalInterface,只允许有一个抽象方法,否则编译器也报错。Java8 中 Runnable 接口就是一个函数式接口,如下:
- @FunctionalInterface
- public interface Runnable {
- /**
- * When an object implementing interface <code>Runnable</code> is used
- * to create a thread, starting the thread causes the object's
- * <code>run</code> method to be called in that separately executing
- * thread.
- * <p>
- * The general contract of the method <code>run</code> is that it may
- * take any action whatsoever.
- *
- * @see java.lang.Thread#run()
- */
- 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表达式,那么一行代码就可以搞定,比较方便。如下代码:
- /*
- * Implementing the interface by creating an
- * anonymous inner class versus using
- * lambda expression.
- */
- 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。
参考: