从 Java 中的 lambda 表达式调用内部接口方法

Inner interface method call from lambda expressions in Java

现在我正在学习Java,我写过这样的代码:

public class LambdaClass {
    public static void main(String args[]) {
        Plane pl = () -> {
            System.out.println("The plane is flying...");
        };

        pl.fly();
    }

    interface Plane {
       void fly();
       //void speedUp(); if I uncomment this, it is an error
    }
}

我对 lambda 表达式和 Plane 接口方法之间的联系很感兴趣,我的意思是 lambda 表达式的主体语句现在分配给了 pl 实例的 fly 方法,为什么会这样?

使用接口的 lambda 实现的一个要求是接口功能,即只有一个方法。

当您使用单个方法定义接口时 fly(),Java 认为它是功能性的,并允许您使用 lambda 来实现它。但是,一旦添加了第二种方法,就不可能使用 lambda 表达式了,因为编译器需要知道您希望实现这两种方法中的哪一种。

解决此问题的一种方法是为每个方法定义单独的功能接口,然后将它们组合成一个更大的接口,如下所示:

interface Flyable {
    void fly();
}
interface WithSpeedIncrease {
    void speedUp();
}
interface WithSpeedDecrease {
    void slowDown();
}
interface Plane extends Flyable, WithSpeedIncrease, WithSpeedDecrease {
}

Lambda 表达式替代匿名内部 class 实现 功能接口

一个 functional interface 是一个只有一个非默认方法的接口,比如你的 Plane 接口。

您的 lambda 表达式相当于匿名内部 class,它使用 lambda 表达式实现该接口的方法。

public static void main(String args[]) {
    Plane pl = new Plane() {
       @Override
       public void fly() {
           System.out.println("The plane is flying...");
       }
    };

    pl.fly();
}

lambda 表达式要简洁得多。

如果取消对接口中第二个方法的注释,它不会编译的原因是它将不再是一个功能接口。 lambda 表达式只能为一种方法提供隐含的方法体。如果接口中有 2 个方法,那么编译器将不会有第二个方法的实现,更不用说无法在等效方法之间进行选择了。