I have the following problem:
There is a generic Factory interface
interface Factory<T> {
T create();
}
Now I have two classes T1 and T2, where T2 is a refinement of T1
class T1 {
}
class T2 extends T1 {
}
and two factories for those types:
interface T1Factory extends Factory<T1> {
public T1 create();
}
interface T2Factory extends Factory<T2> {
public T2 create();
}
For those factories a default implementation will be provided via Generics:
class DefaultFactory<T, F extends Factory<T>> implements Factory<T> {
private F factory;
...
public T create()
{
return factory.create();
}
}
that should be used to implement factories for T1 and T2.
class DefaultT1Factory extends DefaultFactory<T1,T1Factory> {
}
class DefaultT2Factory extends DefaultFactory<T2,T2Factory> {
}
Up to here it works fine. Now the problem. Because T2 is a refinement of T1 the Factory for T2 should be usable also as factory for T1.
This requires T2Factory to be derived from T1Factory. If I do this I cannot use the DefaultFactory class to implement the DefaultT2Factory, because T2Factory is no Factory<T2>. If I add this relationship to the extends clause of T2Factory I got the error that the interface Factory is used more than once. But I need the Factory interface to be able to use the create method in the default implementation.
From the point of method signatures everything is fine. As a consequence I've to duplicate the implementation of the default implementation into the to factory implementation. In my case this coding is quite large and I want to avoid code duplication.
Any idea how to circumvent this problem.
I think you meant
Because T2 is a refinement of T1 the Factory for T1 should be usable also as factory for T2. A factory of T1 should not be used as a factory of T2 because T1 IS NOT T2. However T2 IS T1, so a factory for T2 can be safetly used as a factory of T1(or treated as a factory of T1)
public interface T1Factory<J extends T1> extends Factory<T1> {
public T1 create();
}
Now when you implement this interface, its cool to say something like
public class Foo implements T1Factory<T2> {
public T1 create(){
.....
}
}
Now basically the interface can be parameterized with any type that extends or is T1. In this case you stated you wanted to take advantage of the T2 is a T1 relationship.
Hope that helps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With