Поскольку на самом деле вы не можете создать интерфейс с помощью методов по умолчанию, я думаю, что ваш лучший шанс - это методы stati c.
public interface Function<T, R> {
R apply(T t);
public static <T, V, R> Function<V, R> compose(Function<? super V, ? extends T> before, Function<? super T, ? super R> after) {
return new CombiningFunction<T, V, R>(before, after);
}
public static <T, R, V> Function<T, V> andThen(Function<? super T, ? super R> before, Function<? super R, ? extends V> after) {
return new CombiningFunction<T, V, R>(before, after);
}
static <T> Function<T, T> identity() {
return new Function<T, T> {
T apply(T t) { return t; }
}
}
}
class CombiningFunction<T, V, R> implements Function<T, R> {
Function<T, V> first;
Function<V, R> second;
public R apply(T t) {
V intermediate = first.apply(t);
return second.apply(intermediate);
}
}
Но, как KarelG упоминает в комментариях, на самом деле не рекомендуется сделай это; не говоря уже о том, что это не так элегантно, как в Java 8; в конце концов, функциональные интерфейсы в значительной степени ориентированы на лямбды, и если у вас их нет, любое использование будет таким же неудобным, как и реализация выше.