I have the following 2 interfaces accordingly to abstract factory pattern:
public interface GenericObjectInterface<T extends Number>{
public T getResult();
}
public interface AbstractFactoryInterface{
public <T extends Number> GenericObjectInterface<T> createGenericObject();
}
I have an abstract class implementing GenericObject, but it's still unaware of the concrete type (it does only generic operations on Number):
public abstract class GenericAbstractClass<T extends Number> implements GenericObjectInterface<T>{ }
Then I have a series of concrete class extending that perform generic parameter substitution:
public class IntegerObject extends GenericAbstractClass<Integer>{
public Integer getResult(){}
}
....
Now, from inside an implementation of the factory I build the concrete type, that's implementing GenericObjectInterface but has lost it's generic parameter:
public class ConcreteFactory{
public <T extends Number> GenericObjectInterface<T> greateGenericObject(Class<T> c){
if (c.class.isInstance(Integer.class)){
IntegerObject obj = new IntegerObject();
//I would like to return obj
GenericObjectInterface<T> a = new IntegerObject(); //errror
GenericAbstractClass<T> a = new IntegerObject(); //errror
return a;
}else if (c.class.isInstance(Double.class)){
}
}
}
I would like to return obj that implements GenericObjectInterface but I don't know how can I do it. how can I solve this?
I'm used to abstract factory but I've never used it with generics. Am I doing some mistakes in interpreting the pattern?
If your method returns an IntegerObject
why don't you just return GenericObjectInterface<Integer>
? You already know the parameter type.
In that case, just add a generic parameter to AbstractFactoryInterface
, too:
public interface AbstractFactoryInterface<T extends Number> { ... }
public class ConcreteFactory implements AbstractFactoryInterface<Integer> { ... }
In your implementation the type of T
would be inferred from the assignment, and thus you could do this:
GenericObjectInterface<Double> g = new ConcreteFactory().greateGenericObject();
In that case T
would be Double
but you'd use Integer
internally, resulting in this:
GenericObjectInterface<Double> a = new IntegerCell();
Since the compiler can't ensure that T
will always be of type Integer
it won't allow you to do that assignment.