function界面的概念
当我瞥一眼lambda表达式时,本书涉及一个只有一个抽象方法的function界面 。 我的问题涉及该测验问题
/* 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{ }
我知道最后一个不是,但我认为第一个和第二个应该是function接口。 但是这本书说第二个不是。 为什么? 它不会覆盖add
方法吗? 所以即使在第二,是不是只有一种抽象方法?
一个简单的方法是尝试定义一个实现SmartAdder
的类。 编译器会告诉你需要实现add(int, int)
和add(double, double)
。
可以理解的是,您认为add(double, double)
会覆盖add(int, int)
,但它们实际上是单独的方法,并且可能具有完全不相关的实现。
如果SmartAdder
定义了add(int, int)
的default
实现,它仍然是一个function接口:
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
注释,则接口本身将无法编译。
SmartAdder有两种方法。 方法签名是不同的。 function接口只能有一种方法。
interface SmartAdder
重载 ,而不是覆盖interface Adder
。 那是因为名称相同,但参数类型不同。 因此,它有2个function。 要成为一个function界面,它只需要一个function。
==>只有interface Adder
是一个function界面。
在Java中,子类型中的方法在具有相同签名时会覆盖父类型的方法。 签名表示方法的名称和参数。 特别是,参数必须具有相同的确切类型,并且必须在两种方法中以相同的顺序声明,即子类型中声明的方法的参数类型不能是子类型或类型更广泛的类型。在父类型的方法中声明的参数。
因此,在您的SmartAdder
界面中,带有签名add(double a, double b)
的方法不会覆盖Adder
接口的方法add(int a, int b)
,因为double
比int
宽。 当一个类型有两个或多个具有相同名称但具有不同参数的方法时,它被称为方法重载 ,它与方法重写完全不同。
这就是SmartAdder
最终有两个抽象方法的原因,因此它不是一个function接口(它要求类型只有一个抽象方法)。