有没有办法在功能接口中重载抽象方法?

Is there a way to overload an abstract method in a functional interface?

我希望能够提供一个接受多种不同类型的 lambda 函数的函数式接口。

我读了。这个问题的第一个答案阐明了为什么在功能接口中重载抽象方法会导致未定义的行为。但是,如果我提供所有默认值,有没有办法做等同于重载功能接口中的抽象方法?

我希望能够编写如下代码:

Ball b = () -> System.out.println("You hit it!");
Ball ba = (boolean miss) -> System.out.println(miss);

b.hit();
b.hit(false);
ba.hit();
ba.hit(false);

期望的结果是:

You hit it!
default false
default hit
false

考虑以下(不可编译的)代码(大部分是从链接问题中复制的):

@FunctionalInterface
public interface Ball
{
    void hit();
    void hit(boolean miss);
    default void hit(){
        System.out.println("default hit");
    }
    default void hit(boolean miss){
        System.out.println("default" + miss);
    }

}

我正在寻找可以编译的代码的替代方法。

关于函数式接口的第一件事是,它只能有一个抽象 method.In 这种情况下你甚至都想不到第二种方法(也让它成为抽象方法)。您可以有任意数量的默认方法。

所以答案是 100% 不可能,并且您上面的代码将出现编译错误,因为您保留了 @FunctionalInterface 注释,该注释严格禁止保留一个以上的抽象方法。 根据您的代码

@FunctionalInterface
public interface MyInter {
    public abstract void fly();

    public abstract void fly(int a);

    default void fly() {}          \line1
    default void fly(int g) {   }   \line2
}

第 1 行和第 2 行将抛出编译时错误,因为 java 通过方法名称和参数类型看到它们是相同的,它们永远不会打扰 return 类型或默认值等。 (重载的主要规则)。

此外,如果删除第 1 行和第 2 行,代码也会抛出错误,因为 @functionalinterface 会给出编译错误,说明 invalid '@FunctionalInterface' annotation; MyInter 不是功能接口 .

希望这能回答您的问题...

你可以这样做。但是您需要正确命名您的变量以跟踪 arg 和接受它的 consumer

@FunctionalInterface
interface Ball<T> {
   void hit();

   static <T> Ball<T> withArg(T arg, Consumer<T> com) {
      return () -> com.accept(arg);
   }
}

public class Demo {
   public static void main(String[] args) {
      Ball<Boolean> b = () -> System.out.println("You Hit it!");
      b.hit();
      Ball<Boolean> ba = Ball.withArg(false, a -> System.out.println(a));
      Ball<Boolean> bb = Ball.withArg(true, a -> System.out.println(a));
      ba.hit();
      bb.hit();
   }
}

您可以将接口包装在 class 中,然后在内部将方法调用传递给接口。

示例代码:

public class Test{
    public static void main(String... args) throws Exception{
        Ball b = new Ball(() -> System.out.println("You hit it!"));
        Ball ba = new Ball((boolean miss) -> System.out.println(miss));

        b.hit();
        b.hit(false);
        ba.hit();
        ba.hit(false);
    }

    public static class Ball{
        final Hit a;
        final HitBoolean b;
        
        public Ball(Hit a){
            this.a = a;
            b = (miss) -> System.out.println("default " + miss);
        }
        
        public Ball(HitBoolean b){
            this.b = b;
            a = () -> System.out.println("default hit");
        }
        
        public void hit(){
            a.hit();
        }
        
        public void hit(boolean miss){
            b.hit(miss);
        }
    }

    public interface Hit{
        void hit();
    }
    
    public interface HitBoolean{
        void hit(boolean miss);
    }
}

程序输出:

You hit it!
default false
default hit
false