Home > database >  What is the smartest way to change functional interfaces method name?
What is the smartest way to change functional interfaces method name?

Time:03-02

Somehow I have some requirements to use all benefit of pre-written default methods and change the abstract method(apply(T t)) from Java Function<T, R>.

If I choose to make new @FunctionalInterface extends Function<T, R>, and the method name will be operate(T t), I guess my code will be like below,

@FucntionalInterface
public interface CustomOperator<T, R> extends Function<T, R>{

  R operate(T t);
  
  @override
  default R apply(T t){
    //do something
  } 
}

Let's say all of the client codes which use CustomeOperator only call operate(T t), and if I want the interface to have all the same benefits that the default methods of Function<T ,R> already provide, What is the best approach for filling in the "//do something" parts?

of I want to know whether inheritance is not the smartest(or possible) way for my requirement or not.

CodePudding user response:

The code to fill the //do something space is rather easy: you delegate to your abstract method:

@Override
default R apply(T t) {
    return this.operate(t);
}

The ugly part is all that you need to be aware of and all that you need to keep in mind (all because Function's contract is still going to be visible to your clients):

  • Sub-interfaces and implementing classes of CustomOperator can override apply, and you can't make it final.

  • You'll have to override all those default methods from functions, like this one:

    @Override
    default <V> CustomOperator<V, R> 
                compose(Function<? super V, ? extends T> before) {
    
         Objects.requireNonNull(before); //validation to replicate
         return (V v) -> apply(before.apply(v)); //or operate()
    }
    

    And this, you need to do because your callers work with CustomOperator, which of course doesn't feature on the inherited Function.compose, for example.

  • When java.util.function.Function<T, R> evolves (and evolve it shall), you'll need to keep up.

The above challenges are more a question for your requirements. Why would you need to do that? It's possible, but there's maintenance work coming with it.


And, since you already need to override all default methods from Function, here's a good question to ask: why not just break the problematic inheritance? You can copy the contract but leave CustomOperator independent of Function.

CodePudding user response:

There is only one reasonable implementation:

@Override
default R apply(T t) {
  return operate(t);
}

...and it's perfectly normal to do it that way.

  • Related