为什么Java 8中的函数式接口只有一个抽象方法?

41

正如我们所了解的,在Java 8中,引入了函数式接口的概念。函数式接口有一个abstract方法,同时也可以拥有多个默认方法或静态方法。

但是为什么函数式接口只能有一个抽象方法呢?如果接口有多个抽象方法,为什么它就不能成为函数式接口呢?


7
注意:只要一个接口只有一个抽象方法,它就可以被视为函数式接口,并且可以作为函数式接口使用。注释只是提示程序员这个接口确实是打算用作函数式接口的。因此,可能你想设计一个当前只有一个方法但计划将来扩展的接口。那么它不应该被声明为函数式接口。否则,使用这个接口进行lambda表达式的程序将不能与接口的新版本兼容。 - Zabuzard
1
@Zabuza,这真的解释了一切。可惜它不是一个答案。 - Akabelle
4个回答

37

函数式接口也称为单一抽象方法接口,旨在便于Lambda函数。由于Lambda函数只能为1个方法提供实现,因此函数式接口必须仅有一个抽象方法。更多详情,请参见此处

编辑 -> 另外值得注意的是,函数式接口可以在接口中具有默认实现。您可以在上述链接中找到更多实现细节。


1
不错的链接,我也喜欢这个:http://winterbe.com/posts/2014/03/16/java-8-tutorial/ - Gimby
2
实际上,只允许一个抽象方法的规则有一个例外 - 如果它们由java.lang.Object实现,那么函数式接口可以有另一个抽象方法,例如toString()。 - pkalinow

14
如果Java允许有两个抽象方法,那么lambda表达式将需要提供这两个方法的实现。因为调用方法不知道要调用这两个抽象方法中的哪一个。它可能会调用未实现的方法。例如,如果Java允许这种函数接口。
@FunctionalInterface
interface MyInterface {
    void display();
    void display(int x, int y);
}

然后如果实施以下内容将不可能。

public class LambdaExpression {
    public static void main(String[] args) {
        MyInterface ref = () -> System.out.print("It is display from sout");
        ref.display(2, 3);

    }
}

因为display(int x, int y)没有被实现,所以会导致错误。这就是为什么函数接口是单抽象方法接口的原因。


首先,如果您编写以下代码,编译器将会报错:@FunctionalInterface interface MyInterface { void display(); void display(int x, int y); } - Vishwa Ratna
@CommonMan 这就是我回答的原因 - 为什么Java没有允许它。而且,我觉得上面的回答不够详细。这就是为什么我只发了这个帖子。 - sn.anurag
看看Adityakryal给出的答案,你有没有添加任何新内容? - Vishwa Ratna
@sn.anurag 我仍然无法理解这个问题。当我有不同的方法签名时,为什么编译器不能区分 () -> 和 (x,y) -> 呢? - rakesh kashyap
@rakeshkashyap 编译器可以区分,但你应该为实例提供两种方法的实现。然而,你无法做到这一点。对于一个实例,你只能使用lambda表达式为最多一个方法提供实现。 - sn.anurag

5

功能接口让我们可以将一个对象当作函数调用,这样我们可以传递动词(函数)而非名词(对象)来处理程序。功能接口的实现执行一个单一、明确定义的操作,就像任何方法应该做的那样,使用像run、execute、perform、apply或其他通用动词的名称[1]。

  1. Scala和Clojure中的函数编程模式。

0
如果在接口中定义多个抽象方法是可能的。但是,如果在接口顶部定义为@FunctionalInterface,则会出现编译时错误“无效的'@FunctionalInterface'注释Interf不是一个功能接口”。 即使实现也不可能,因为编译器无法猜测方法的类型推断(不兼容类型Interf不是功能接口 接口Interf中有多个非重写抽象方法) 例如1:-
@FunctionalInterface
interface Interf {
   public void m1();
   public void m2();
 }//error:-Invalid '@FunctionalInterface' annotation Interf  not a functional interface

例2:-

interface Interf {
   public void m1();
   public void m2();
}
public class abc1 {
    public static void main(String args[]) {
        interf interf = () -> System.out.println("we impl");
        interf.m1();
    }
}//incompatible types Interf is not a functional interface
multiple non-overriding abstract methods in interface Interf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接