简体   繁体   English

为什么我们不能在功能界面中重载抽象方法? (JAVA)

[英]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.

相关问题 有没有办法在功能接口中重载抽象方法? - Is there a way to overload an abstract method in a functional interface? 为什么我们不能在没有匿名类方法的情况下在java中实例化接口或抽象类? - Why can't we instantiate an interface or an abstract class in java without an anonymous class method? 当我们在一个接口中添加两个抽象方法并只实现一个方法时,为什么我们不能使用 lambda 实现另一个方法? - When we add two abstract methods in an interface and implement just one method then why can't we implement the other method using lambda? 为什么我们需要Java中的Predicate功能接口? - Why we need Predicate functional interface in Java? 为什么在Java Stream接口中重载()的varargs方法? - Why overload the varargs method of() in Java Stream interface? 在Java中,为什么在我们定义一个接口时不需要将其标记为抽象? - In Java, why don't we need to mark a class as abstract when we define an interface in it? 我可以在Java中重载接口方法吗? - Can I overload an interface method in Java? 为什么我们不能在Java中使用抽象构造函数? - Why can't we have abstract constructor in java? 为什么我们不能在 Java 中实例化抽象类? - Why can't we instantiate an abstract class in Java? 我们可以重载Java中的main()方法吗? - Can we overload the main() method in Java?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM