简体   繁体   English

Java为什么我不能在函数接口中使用多重继承

[英]Java why can't I use multiple inheritance with functional interfaces

I was making a small library for Java, and part of the api was a functional interface (and thus, lambda expressions) that took 3 arguments. 我当时正在为Java创建一个小型库,而api的一部分是一个带有3个参数的功能接口(因此是lambda表达式)。 I realized that two of them might often be unwanted. 我意识到其中两个可能经常是多余的。 So I thought to make something like this: 所以我想做这样的事情:

class Main {

  public static void main(String[] args) {
    call((s) -> System.out.println(s));
  }

  static void call(A a) {
    a.call(7, 42, "Hello World!");
  }

  static interface A {

    void call(int x, int y, String s);

  }

  static interface B extends A {

    void call(String s);

    default void call(int x, int y, String s) {
      call(s);
    }

  }

}

I expected that users could then insert the first two parameters if they wanted, but if they didn't they could leave them out and they would be ignored. 我希望用户然后可以根据需要插入前两个参数,但是如果不这样做,则可以将其省略而将其忽略。 However, when I tried to compile the above code, I got a compile-time exception with the message "incompatible types: incompatible parameter types in lambda expression". 但是,当我尝试编译以上代码时,出现了编译时异常消息,消息为“不兼容的类型:lambda表达式中的参数类型不兼容”。 Why does this not work? 为什么这不起作用?

Your static void call(A a) method requires a parameter of type A , or a lambda expression that satisfies the SAM method signature that you have defined on it. 您的static void call(A a)方法需要一个类型为A的参数,或者是一个满足您在其上定义的SAM方法签名的lambda表达式。 That's why it will complain that you are just passing 1 parameter when it is actually expecting 3. If you want to pass a lambda expression of type B you must cast it first like this: 这就是为什么它会抱怨您实际上只是在传递3时才传递1参数。如果要传递类型B的Lambda表达式,则必须首先将其强制转换为:

call((B)(s) -> System.out.println(s));

Or you can edit your static void call method to accept a parameter of type B . 或者,您可以编辑您的static void call方法以接受类型B的参数。

The method call(A a) takes instance of interface A as an argument and in interface A the method call is taking 3 arguments: void call(int x, int y, String s); 方法call(A a)以接口A实例作为参数,而在接口A ,方法调用采用3个参数: void call(int x, int y, String s); so it looks like you want to declare your argument as an instance of interface B - not A 所以看起来您想将参数声明为接口B的实例-而不是A

So modifying: 所以修改:

static void call(A a) {
    a.call(7, 42, "Hello World!");
 }

to: 至:

static void call(B b) {
    b.call(7, 42, "Hello World!");
 }

will solve the issue 将解决问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM