Why can't we overload a abstract method in a functional interface? (Java)

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. Citing from the oracle docs:

Overloading Methods

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);
}

Why this works is explained in the documentation for FunctionalInterface:

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