[英]Why can't we overload a abstract method in a functional interface? (Java)
所以我熟悉java中的函数接口,以及它们与lambda表达式的使用。 功能界面只能包含一个抽象方法。 当从lambda表达式中使用这个孤独的方法时,您不需要指定它的名称 - 因为接口中只有一个抽象方法,编译器知道这是您引用的方法。
例:
// Functional Interface:
@FunctionalInterface
public interface Ball
{
void hit();
}
// Lambda to define, then run the hit method:
Ball b = () -> System.out.println("You hit it!");
b.hit();
虽然很明显为什么功能接口只能包含一个抽象方法,但我不明白为什么不能重载该方法。
例如,以下内容将无法编译:
// (NOT) Functional Interface:
@FunctionalInterface
public interface Ball
{
void hit();
void hit(boolean miss);
}
// Lambda to define, then run the hit method:
Ball b = () -> System.out.println("You hit it!");
Ball ba = (boolean miss) -> System.out.println(miss);
b.hit();
ba.hit(false);
编译器声明Ball
接口不起作用,因为它包含多个方法,但在这种情况下我不明白为什么这会是一个问题 - 只要两个方法采用不同的参数,就应该可以推断出哪个方法我根据我定义的参数在lambda中引用。
有人可以解释为什么不能在功能界面中重载抽象方法吗?
在没有方法重载的语言中,方法由它们在该类中的名称唯一标识(暂时忽略覆盖)。
在Java中,事情有点不同。 引用oracle文档 :
重载方法
Java编程语言支持重载方法,Java可以区分具有不同方法签名的方法。 这意味着如果类中的方法具有不同的参数列表,则它们可以具有相同的名称(有一些资格,将在标题为“接口和继承”的课程中讨论)。
所以我们知道方法也通过它们的签名来识别。 如果两个方法共享一个名称但没有相同的签名,则它们是不同的方法 。 不要让他们的共同名称欺骗你认为他们有某种关联。
考虑到这一事实,我们可以轻松地创建一个示例,如果方法按照您描述的方式运行,则会发生未定义的行为:
Ball ba = (boolean miss) -> System.out.println(miss);
someFunction(ba)
public void someFunction(Ball ball) {
ball.hit();
}
在这种情况下你会期待什么行为? 它是未定义的!
但是,您可以使用默认方法 。 我不太了解你的情况,以判断这是否合适,但你可以这样做:
@FunctionalInterface
public interface Ball
{
default void hit() {
hit(true);
}
void hit(boolean miss);
}
为什么这个工作在FunctionalInterface
的文档中解释:
从概念上讲,功能界面只有一种抽象方法。 由于默认方法具有实现,因此它们不是抽象的
只要您声明一个实现Ball
接口的类,就必须实现所有抽象方法。 例如,如果你这样做:
Ball b = () -> System.out.println("You hit it!");
然后你传递b
作为参数,而其他代码调用b.hit(true)
,它会粉碎,因为没有实现hit(boolean miss)
。
因此功能接口必须只有一个抽象方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.