@FunctionalInterface inheritance

Viewed 280

Say I have the following interface:

@FunctionalInterface
public interface First {
   int fun(int a);
}

and also

@FunctionalInterface
public interface Second extends First {
   default int fun(int a) { fun(a, a); }

   int fun(int a, int b);
}

Then if I have a method somewhere that takes a First I can do, for example:

methodThatTakeFirst(val -> val + 1);

But I also want to be able to pass a Second, like:

methodThatTakeFirst((v1, v2) -> v2 * v2);

However this only works if I cast the lambda like this:

methodThatTakeFirst((Second) (v1, v2) -> v2 * v2);

My question is: is there a way to design this pattern without having to cast the lambdas to the subinterface? Or what would be the most elegant way to handle this scenarios?

2 Answers

You could overload methodThatTakeFirst, so that it also accepts an instance of Second as an argument, and delegate to methodThatTakeFirst(First first):

void methodThatTakeFirst(First first) {
    // play with first
}

void methodThatTakeFirst(Second second) {
    methodThatTakeFirst((First) second); // casting necessary
}

The cast is crucial, so that the compiler actually delegates to methodThatTakeFirst(First first), otherwise you'd end up with a StackOverflowError.

Whether this is a good design or not, I don't know, but I think it's outside the scope of this question.

Maybe just add another lambda?

  void secondMethod(Second second) {
      methodThatTakeFirst(x-> second.fun(x,x)); 
  }
Related