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 overrideapply
, 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 inheritedFunction.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.