【问题标题】:Concept of functional interface功能接口的概念
【发布时间】:2017-06-07 23:49:59
【问题描述】:

当我浏览 lambda 表达式时,本书涉及到一个只有一个抽象方法的函数式接口。我的问题解决了那个测验问题

/* Which of these interfaces are functional interfaces? */
public interface Adder{
   int add(int a, int b);
}
public interface SmartAdder extends Adder{
   int add(double a, double b);
}
public interface Nothing{
}

我知道最后一个不是,但我认为第一个和第二个应该是功能接口。但书上说第二个不是。为什么?它不会覆盖add 方法吗?那么即使是第二个,抽象方法不就只有一个吗?

【问题讨论】:

  • "它不会覆盖 add 方法吗?" - 不。一个方法必须与另一个方法具有相同的签名才能覆盖它。
  • 如果你用@FunctionalInterface注释一个接口,编译器会告诉你它是否是一个函数接口。
  • 是的。你说的对。这绝对是我没有注意到的。 @user2357112

标签: java java-8 functional-interface


【解决方案1】:

找出一个简单的方法是尝试定义一个实现SmartAdder 的类。编译器会告诉你需要同时实现add(int, int)add(double, double)

您认为add(double, double) 会覆盖add(int, int) 是可以理解的,但它们实际上是独立的方法,并且可能具有完全不相关的实现。

如果SmartAdder 定义了defaultadd(int, int) 实现,它仍将是一个功能接口:

public interface SmartAdder extends Adder {
   int add(double a, double b);

   default int add(int a, int b) {
     return add((double)a, (double)b); // this calls the double method instead
  }
}

您可能还遇到过@FunctionalInterface 注释 - 这可以放在接口上以在编译时强制接口只有一个抽象方法。如果SmartAdder 带有@FunctionalInterface 注释,则接口本身将无法编译。

【讨论】:

  • 感谢您和所有回答者 +1。这绝对是我没有注意到的。
【解决方案2】:

SmartAdder 有两种方法。方法签名不同。函数式接口只能有一种方法。

【讨论】:

    【解决方案3】:

    在 Java 中,子类型中的方法覆盖父类型的方法,如果它具有相同的签名。签名意味着方法的名称和参数。特别是,参数必须具有相同的确切类型,并且必须在两种方法中以相同的确切顺序声明,即子类型中声明的方法的参数类型不能是子类型或比类型更宽的类型在父类型的方法中声明的参数。

    因此,在您的SmartAdder 接口中,带有签名add(double a, double b) 的方法不会覆盖Adder 接口的方法add(int a, int b),因为doubleint 更宽。当一个类型有两个或多个同名但参数不同的方法时,称为方法重载,它与方法重载完全不同。

    这就是SmartAdder 最终有两个抽象方法的原因,因此它不是函数式接口(它要求类型只有一个抽象方法)。

    【讨论】:

      【解决方案4】:

      interface SmartAdder 重载,而不是覆盖interface Adder。那是因为名称相同,但参数类型不同。因此,它有 2 个功能。要成为一个函数式接口,它只需要一个函数。

      ==> 只有interface Adder 是功能接口。

      【讨论】:

        猜你喜欢
        • 2015-05-23
        • 2016-08-30
        • 2014-07-15
        • 1970-01-01
        • 2013-10-18
        • 2016-08-25
        • 2011-10-20
        • 2016-11-15
        • 1970-01-01
        相关资源
        最近更新 更多