函数式接口是在Java8里跟随lambda表达式一起提出的,学习lambda表达式之前,还是先了解一下什么是“函数式接口”。

  • 概念


函数式接口就是指只含有一个抽象函数的接口。这个接口里可以包含任意多个默认方法,任意多个静态方法。函数式接口可以使用注解@FunctionalInterface标注,如果被标注的接口不符合条件,在编译器里会提示错误。

@FunctionalInterface
public interface FunInterface {

    /**
     * 抽象方法
     */
    void abstractSay();

    /**
     * 默认方法
     */
    default void defaultSay() {
        System.out.println("defaultSay");
    }

    /**
     * 静态方法
     */
    static void staticSay() {
        System.out.println("staticSay");
  

如上面的例子所示,自定义的接口FunInterface就是一个函数式接口,并且使用了注解标注。这个接口里定义了一个默认方法和一个静态方法,都没有影响它是一个函数式接口的本质。

  • 注意事项

函数式接口和普通的接口一样,可以有实现类。

public class FunInterfaceImpl implements FunInterface {

    @Override
    public void abstractSay() {
        System.out.println("abstractSay");
    }
}

 

函数式接口的条件是只含有一个抽象方法,所以如果存在接口继承,要求继承下来的所有方法中只能有一个抽象方法。

@FunctionalInterface
public interface SubFunInterface extends FunInterface {

    /**
     * 子类的抽象方法
     */
    void subAbstractSay();
}

子接口SubFunInterface中也声明了一个抽象方法subAbstractSay,又从父类FunInterface中继承了抽象方法abstractSay,所以不再满足函数式接口的条件,因此使用注解@FunctionalInterface将会提示错误!

 

函数式接口的抽象方法如果覆盖Object类中的public方法,那么不算在“函数式接口只含有一个抽象方法”限制之内。

@FunctionalInterface
public interface FunInterface {

    /**
     * 抽象方法
     */
    void abstractSay();

    /**
     * 覆盖了Object.toString()方法
     * @return
     */
    String toString();

    /**
     * 默认方法
     */
    default void defaultSay() {
        System.out.println("defaultSay");
    }

    /**
     * 静态方法
     */
    static void staticSay() {
        System.out.println("staticSay");
    }
}

这个代码在上面的例子里又新增了一个抽象方法toString,但是使用注解@FunctionalInterface仍然没错,它仍是一个函数式接口。因为这里的toString方法是覆盖的Object类中的public方法。另外,看下面的代码块:

@FunctionalInterface
public interface FunInterface {

    /**
     * 抽象方法
     */
    void abstractSay();

    /**
     * 覆盖了Object.toString()方法
     * @return
     */
    String toString();

    /**
     * 覆盖了Object.clone()方法
     * 但是不是public 而是protected
     * @return
     */
    Object clone();

    /**
     * 默认方法
     */
    default void defaultSay() {
        System.out.println("defaultSay");
    }

    /**
     * 静态方法
     */
    static void staticSay() {
        System.out.println("staticSay");
    }
}

这个函数式接口就是错误的,因为包含了多个抽象方法,虽然clone()方法来自Object类,但是这不是一个public方法,因为不能算作“例外”。

版权声明:本文为anivia原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/anivia/p/10063808.html