为什么我们不能在功能接口中重载抽象方法? (Java) [英] Why can't we overload a abstract method in a functional interface? (Java)

查看:296
本文介绍了为什么我们不能在功能接口中重载抽象方法? (Java)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我熟悉Java中的功能接口以及它们与lambda表达式的结合使用.一个功能接口只能包含一个抽象方法.在lambda表达式中使用此孤独方法时,无需指定其名称-由于接口中只有一个抽象方法,因此编译器知道您正在引用的方法.

So I am familiar with functional interfaces in java, and their use with lambda expressions. 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.

示例:

// 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.

例如,以下内容将不会编译:

// (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中引用的方法.

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.

有人可以解释为什么无法在功能接口内重载抽象方法吗?

推荐答案

在没有方法重载的语言中,方法由该类中的名称唯一标识(暂时忽略重写).

In languages without method overloading, methods are uniquely identified by their name in that class (ignoring overriding for the moment).

在Java中,情况有所不同.引用 Oracle文档:

In Java things are a little different though. Citing from the oracle docs:

重载方法

Java编程语言支持重载方法,Java可以区分具有不同方法签名的方法.这意味着,如果类中的方法具有不同的参数列表,则它们可以具有相同的名称(对此有一些限定条件,将在标题为接口与继承"的课程中进行讨论).

The Java programming language supports overloading methods, and Java can distinguish between methods with different method signatures. 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);
}

文档中对此原因进行了解释FunctionalInterface :

从概念上讲,功能接口只有一种抽象方法.由于默认方法具有实现方式,因此它们不是抽象的

Conceptually, a functional interface has exactly one abstract method. Since default methods have an implementation, they are not abstract

这篇关于为什么我们不能在功能接口中重载抽象方法? (Java)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆