I want to make a generic interface that has two abstract methods, and one of them returns and consumes sub-type with same generic type of the interface.
The goal I want to achieve is that creating @FunctionalInterfaces
having same parents, but different way of composing themselves.
My first approach is as below,
public interface ParentFunction<T, C extends ParentFunction> {
void doSomething(T t);
C<T> compose(C<T> other);
}
@FunctionalInterface
public interface SonFunction<T> extends ParentFunction<T, SonFunction> {
@Override
default SonFunction<T> compose(SonFunction<T> other){
return null;
}
}
@FunctionalInterface
public interface SonFunction<T> extends ParentFunction<T, SonFunction> {
@Override
default DaughterFunction<T> compose(SonFunction<T> other){
return null;
}
}
But an compile error occurs at C<T>
of parent method saying, 'Type "C" does not have type parameters,' and another at @Override
of child default method.
I can just separate my child interfaces without extending, but I hope them to have an super-type that the client code will only knows.
Is there any cool technique that I may use to achieve it?
CodePudding user response:
In Java, you cannot do C<T>
, however, you can require C to extend ParentFunction<T,C>
Same applies to your SonFunction
and DaughterFunction
.
Try this:
public interface ParentFunction<T, C extends ParentFunction<T, C>> {
void doSomething(T t);
C compose(C other);
}
@FunctionalInterface
public interface SonFunction<T> extends ParentFunction<T, SonFunction<T>> {
@Override
default SonFunction<T> compose(SonFunction<T> other){
return null;
}
}
@FunctionalInterface
public interface DaughterFunction<T> extends ParentFunction<T, DaughterFunction<T>> {
@Override
default DaughterFunction<T> compose(DaughterFunction<T> other){
return null;
}
}