[英]Why can't we overload a abstract method in a functional interface? (Java)
So I am familiar with functional interfaces in java, and their use with lambda expressions. 所以我熟悉java中的函数接口,以及它们与lambda表达式的使用。 A functional interface can only contain one abstract method.
功能界面只能包含一个抽象方法。 When using this lonely method from a lambda expression, you do not need to specify its name - since there is only one abstract method in the interface, the compiler knows that's the method you are referencing.
当从lambda表达式中使用这个孤独的方法时,您不需要指定它的名称 - 因为接口中只有一个抽象方法,编译器知道这是您引用的方法。
Example: 例:
// 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();
Although it is obvious why a functional interface can only contain one abstract method, I do not understand why it is not possible to overload that method. 虽然很明显为什么功能接口只能包含一个抽象方法,但我不明白为什么不能重载该方法。
For example, the following will not compile: 例如,以下内容将无法编译:
// (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);
The compiler states that the Ball
interface is not functional because it contains more than one method, but in this case I do not understand why this would be a problem - As long as the two methods take different parameters, it should be possible to infer which method I'm referencing in the lambda based on what parameters I define. 编译器声明
Ball
接口不起作用,因为它包含多个方法,但在这种情况下我不明白为什么这会是一个问题 - 只要两个方法采用不同的参数,就应该可以推断出哪个方法我根据我定义的参数在lambda中引用。
Can someone explain why it is not possible to overload a abstract method within a functional interface? 有人可以解释为什么不能在功能界面中重载抽象方法吗?
In languages without method overloading, methods are uniquely identified by their name in that class (ignoring overriding for the moment). 在没有方法重载的语言中,方法由它们在该类中的名称唯一标识(暂时忽略覆盖)。
In Java things are a little different though. 在Java中,事情有点不同。 Citing from the oracle docs :
引用oracle文档 :
Overloading Methods
重载方法
The Java programming language supports overloading methods, and Java can distinguish between methods with different method signatures.
Java编程语言支持重载方法,Java可以区分具有不同方法签名的方法。 This means that methods within a class can have the same name if they have different parameter lists (there are some qualifications to this that will be discussed in the lesson titled "Interfaces and Inheritance").
这意味着如果类中的方法具有不同的参数列表,则它们可以具有相同的名称(有一些资格,将在标题为“接口和继承”的课程中讨论)。
So we know that methods are also identified by their signature. 所以我们知道方法也通过它们的签名来识别。 If two methods share a name but don't have the same signature, they are different methods .
如果两个方法共享一个名称但没有相同的签名,则它们是不同的方法 。 Don't let their shared name fool you into thinking that they are somehow related.
不要让他们的共同名称欺骗你认为他们有某种关联。
Considering this fact, we can easily create an example in which undefined behavior would occur if methods behaved the way you described: 考虑到这一事实,我们可以轻松地创建一个示例,如果方法按照您描述的方式运行,则会发生未定义的行为:
Ball ba = (boolean miss) -> System.out.println(miss);
someFunction(ba)
public void someFunction(Ball ball) {
ball.hit();
}
What behavior would you expect in this case? 在这种情况下你会期待什么行为? It is undefined!
它是未定义的!
You can — however — make use of default methods . 但是,您可以使用默认方法 。 I don't know your situation well enough to judge if this is a suitable approach, but you can do this:
我不太了解你的情况,以判断这是否合适,但你可以这样做:
@FunctionalInterface
public interface Ball
{
default void hit() {
hit(true);
}
void hit(boolean miss);
}
Why this works is explained in the documentation for FunctionalInterface
: 为什么这个工作在
FunctionalInterface
的文档中解释:
Conceptually, a functional interface has exactly one abstract method.
从概念上讲,功能界面只有一种抽象方法。 Since default methods have an implementation, they are not abstract
由于默认方法具有实现,因此它们不是抽象的
As long as you are declairing a class which implements Ball
interface,you must implements all the abstract methods. 只要您声明一个实现
Ball
接口的类,就必须实现所有抽象方法。 For example,if you do it like this: 例如,如果你这样做:
Ball b = () -> System.out.println("You hit it!");
then you pass b
as a parameter,and other code call b.hit(true)
,it will crush,because hit(boolean miss)
is not implemented. 然后你传递
b
作为参数,而其他代码调用b.hit(true)
,它会粉碎,因为没有实现hit(boolean miss)
。
So a functional interface must only have one abstract method. 因此功能接口必须只有一个抽象方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.