Java 8我爱编程

Java 8 | 函数式接口

2018-04-14  本文已影响58人  懒癌正患者

在前面我们学习了 lambda 表达式和函数式接口的基本概念,接下来我们再深入了解一下函数式接口。

什么是函数式接口

函数式接口也可以称为 Single Abstract Method interfaces (SAM Interfaces),只允许接口中有唯一的抽象方法。在 Java 8 提供了 @FunctionalInterface 注解,在接口不符合函数式接口要求时编译器会报错。函数式接口可以是 lambda 表达式、方法引用或者构造函数引用等等。

举个例子

@FunctionalInterface
public interface MyFirstFunctionalInterface {
     public void firstWork();
}

尝试在添加一个抽象方法

@FunctionalInterface
public interface MyFirstFunctionalInterface {
    public void firstWork();
    public void doSomeMoreWork();
}

上面这个接口编译器将会报错

编译报错

注意事项

A) 正如上面例子中,函数式接口只允许有一个抽象方法,第二个抽象方法是不允许出现在函数式接口中的。如果把 @FunctionInterface 注释去掉,编译器将不会报错,但是这个接口就不是函数式接口了。

B) @FunctionalInterface 只是一个标识,通知编译器这是一个函数式接口,当你编写的接口不符合函数式接口,编译器就会提醒你。就算不用 @FunctionalInterface 注解标识某个接口,只要这个接口符合函数式接口的规则,这个接口仍然是函数式接口。

C) 由于默认方法有实现方式,所以不是抽象的。因此可以在函数式接口中添加任意多个默认方法(你高兴就好)。

下面这个函数式接口是有效的

@FunctionalInterface
public interface MyFirstFunctionalInterface {

    public void firstWork();

    default void doSomeMoreWork1(){
        //Method body
    }

    default void doSomeMoreWork2(){
        //Method body
    }
}

D) 如果接口中声明的是java.lang.Object 类中的 public 方法,那么这些方法不算做是函数式接口的抽象方法。因为任何一个实现接口的类都会有这些方法的默认实现,这些方法的时候可能来自于 java.lang.Object 或者其他类。Comparator 是一个函数式接口,尽管它声明了2个抽象方法,为啥呢?因为其中一个方法是是 equals() 方法,这个方法的签名和 java.lang.Object 中的 equals() 方法相同,所以不算做事抽象方法。

下面这个函数式接口任然有效

@FunctionalInterface
public interface MyFirstFunctionalInterface {
    public void firstWork();

    @Override
    public String toString();                //Overridden from Object class
    
    @Override
    public boolean equals(Object obj);        //Overridden from Object class
}

函数式接口在前面的文章中也多次提到,这里只是简单的总结了一下。

欢迎关注我的微信公众号:java初学者的日常

java初学者的日常
上一篇 下一篇

猜你喜欢

热点阅读