30

在 Java 8 中引入了lambda 表达式来帮助减少样板代码。如果接口只有一种方法,它可以正常工作。如果它由多个方法组成,那么这些方法都不起作用。如何处理多种方法?

我们可以去下面的例子

public interface I1()
{
    void show1();
    void show2();
}

那么主函数的结构将是什么来定义主函数本身的方法呢?

4

4 回答 4

36

正如 Eran 所说,Lambda 表达式仅可用于功能接口,但如果您确实需要接口中的多个方法,您可以将修饰符更改为defaultorstatic并在必要时在实现它们的类中覆盖它们。

public class Test {
    public static void main(String[] args) {
        I1 i1 = () -> System.out.println(); // NOT LEGAL
        I2 i2 = () -> System.out.println(); // TOTALLY LEGAL
        I3 i3 = () -> System.out.println(); // TOTALLY LEGAL
    }
}

interface I1 {
    void show1();
    void show2();
}

interface I2 {
    void show1();
    default void show2() {}
}

interface I3 {
    void show1();
    static void show2 () {}
}

遗产

你不应该忘记继承的方法。

在这里,I2继承show1show2因此不能是功能接口。

public class Test {
    public static void main(String[] args) {
        I1 i1 = () -> System.out.println(); // NOT LEGAL BUT WE SAW IT EARLIER
        I2 i2 = () -> System.out.println(); // NOT LEGAL
    }
}

interface I1 {
    void show1();
    void show2();
}

interface I2 extends I1 {
    void show3();
}

注解

为确保您的接口是功能接口,您可以添加以下注解@FunctionalInterface

@FunctionalInterface <------- COMPILATION ERROR : Invalid '@FunctionalInterface' annotation; I1 is not a functional interface
interface I1 {
    void show1();
    void show2();
}

@FunctionalInterface
interface I2 {
    void show3();
}
于 2016-03-26T09:11:41.713 回答
14

Lambda 表达式只能用于实现功能接口,即具有单个抽象方法的接口。lambda 表达式无法实现具有两个抽象方法的接口。

于 2016-03-26T09:06:07.027 回答
13

我一般直接在接口中创建静态工厂方法:

public inteface I1 {
    void show1();
    void show2();

    public static I1 of(Runnable show1, Runnable show2) {
        return new I1() {
            void show1() { show1.run(); }
            void show2() { show2.run(); }
        };
    }
}

用法:

I1 i1 = I1.of(() -> System.out.println("show1"), () -> System.out.println("show2"));
于 2016-03-26T10:24:31.853 回答
4

您始终可以使用组合:

public inteface I1 {
    void show1();
    void show2();
}

public class I1Adapter {
    private final Runnable r1,r2;
    public I1Adapter(Runnable r1, Runnable r2) {this.r1=r1; this.r2=r2;}
    public void show1() {r1.run();}
    public void show2() {r2.run();}
    public static I1Adapter compose(Runnable r1, Runnable r2) {
        return new I1Adapter(r1,r2);
    }
}

不,您可以这样做(使用静态导入):

I1 i1 = compose(()->foo(), ()->bar());
于 2016-03-26T09:15:49.810 回答