I am writing a program that needs to do CRUD operations with sub-classes of an abstract object Assignment
. I have factories to do the CRUD operations, but I am having a problem overriding the methods.
public abstract class Assignment {
protected Integer id = null;
protected String name = null;
public Assignment() {}
public Assignment(Assignment original) { // code here to clone }
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
a concrete assignment
public class DCONAssignment extends Assignment {
protected Integer amount = null;
protected String type = null;
public DCONAssignment() {}
public DCONAssignment(DCONAssignment original) { // code here to clone }
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
abstract factory
public abstract class AssignmentProcessor {
public abstract Assignment loadAssignment(Integer assignmentId);
// public abstract boolean saveAssignment(Assignment assignment); // option 1
// public abstract boolean saveAssignment(<? extends Assignment> assignment); // option 2 // This says "abstract methods do not specify a body"
// public <T extends Assignment> boolean saveAssignment(T assignment) { //option 3
public boolean saveAssignment(Assignment assignment) { //option 4
return false;
}
protected Assignment loadAssignment(Integer assignmentId, Class<? extends Assignment> clazz) {
Assignment assignment = null;
try {
assignment = clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
BurstAssignment burstAssignment = null; // load assignmnet from db
assignment.setId(burstAssignment.getId());
return assignment;
}
}
and concrete factory
public class DCONAssignmentProcessor extends AssignmentProcessor {
@Override
public DCONAssignment loadAssignment(Integer assignmentId) {
DCONAssignment assignment = (DCONAssignment) loadAssignment(assignmentId, DCONAssignment.class);
return assignment;
}
@Override
public boolean saveAssignment(DCONAssignment assignment) { // eclipse says I need to override a method with options 1, 3 and 4
return false;
}
}
In conclusion, the abstract factory handles some of the heavy lifting for loading an Assignment. The concrete factories handle details for their particular implementation of the Assignment class. The problem is overriding the abstract methods with concrete parameters. So the question is, how can I specify a method in the abstract factory and override it with a concrete parameter in the concrete factory?
I solved the problem the solution was to make the abstract factory generic
public abstract class AssignmentProcessor<T extends Assignment> {
public abstract T loadAssignment(Integer assignmentId);
public boolean saveAssignment(T assignment) {
return false;
}
protected Assignment loadAssignment(Integer assignmentId, Class<T> clazz) {
Assignment assignment = null;
try {
assignment = clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BurstAssignment burstAssignment = SessionHelper.getSession().getBurstAssignment(assignmentId);
assignment.setId(burstAssignment.getId());
return assignment;
}
}
concrete factory
public class DarfAssignmentProcessor extends AssignmentProcessor<DarfAssignment> {
@Override
public DarfAssignment loadAssignment(Integer assignmentId) {
DarfAssignment assignment = (DarfAssignment) loadAssignment(assignmentId, DarfAssignment.class);
return assignment;
}
@Override
public boolean saveAssignment(DarfAssignment assignment) {
return false;
}
}