Java 如何使用工厂子类中的子类覆盖超类工厂中的抽象类?

Java 如何使用工厂子类中的子类覆盖超类工厂中的抽象类?,java,subclassing,abstract-factory,Java,Subclassing,Abstract Factory,我正在编写一个程序,需要对抽象对象的子类执行CRUD操作赋值。我有工厂来做CRUD操作,但是我在重写方法时遇到了一个问题 public abstract class Assignment { protected Integer id = null; protected String name = null; public Assignment() {} public Assignment(Assignment original) { // code here to

我正在编写一个程序,需要对抽象对象的子类执行CRUD操作
赋值
。我有工厂来做CRUD操作,但是我在重写方法时遇到了一个问题

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; }
}
具体的任务

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; }
}
抽象工厂

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;
    }
}

总之,抽象工厂为装载任务处理一些繁重的工作。具体的工厂处理分配类的特定实现的细节。问题是用具体参数覆盖抽象方法。所以问题是,我如何在抽象工厂中指定一个方法并在具体工厂中用具体参数覆盖它?

我解决了这个问题,解决方案是使抽象工厂通用化

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;
    }
}
公共抽象类赋值处理器{
公共抽象T loadAssignment(整数assignmentId);
公共布尔存储赋值(T赋值){
返回false;
}
受保护的分配loadAssignment(整数分配ID,类clazz){
赋值=null;
试一试{
赋值=clazz.newInstance();
}捕获(实例化异常|非法访问异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
BurstAssignment BurstAssignment=SessionHelper.getSession().getBurstAssignment(assignmentId);
assignment.setId(burstAssignment.getId());
返回任务;
}
}
混凝土厂

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;
    }
}
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;
    }
}
公共类DarfAssignmentProcessor扩展了AssignmentProcessor{
@凌驾
公共DARFASignment loadAssignment(整数assignmentId){
Darfasignment赋值=(Darfasignment)loadAssignment(assignmentId,Darfasignment.class);
返回任务;
}
@凌驾
公共布尔存储分配(DARFASSIGNATION分配){
返回false;
}
}

JSYK:您不必重写
dconaSignment
中的
getId
setId
getName
setName
方法。它们是从基类继承的,而您实际上并没有对它们进行更改


当您使用
@Override
时,您正在告诉编译器您想要创建的方法用新方法替换父类中的方法。这意味着您希望父类有一个具有相同名称和签名的方法。如果编译器查找时找不到具有相同名称和签名的方法,则生成错误。Eclipse接受错误,检查您的代码,并为您提供关于如何修复该问题的建议

选项1:
公共抽象布尔存储分配(分配)

基类定义了一个带有
赋值
参数的方法。
DCONAssignment
是一个
赋值
,因此您可以在派生类中简单地定义
saveAssignment
方法来接受
赋值
,并传入
DCONAssignment
对象

要正常运行,必须强制转换派生方法:

@Override
public boolean saveAssignment(Assignment assignment) {
    if (assignment instanceof DCONAssignment)) {
        DCONAssignment da = (DCONAssignment) assignment;
        // ... save da 
        return true;
    } else {
        throw new IllegalArgumentException("Expected DCONAssignment");
    }
}

选项2:
public abstract boolean saveAssignment(而不是
public boolean saveAssignment(T assignment){return false;}
在基类中,可以使saveassign抽象
public abstract boolean saveAssignment(T assignment);
,这需要派生类提供实现。
@Override
public boolean saveAssignment(<? extends Assignment> assignment) {
    if (assignment instanceof DCONAssignment) {
        DCONAssignment da = (DCONAssignment) assignment;
        // ... save da 
        return true;
    } else {
        throw new IllegalArgumentException("Expected DCONAssignment");
    }
}
public abstract class AssignmentProcessor<T extends Assignment> {
    public abstract T loadAssignment(Integer assignmentId);
    public abstract boolean saveAssignment(T assignment);
}
public class DCONAssignmentProcessor extends AssignmentProcessor<DCONAssignment> {
    @Override
    public DCONAssignment loadAssignment(Integer assignmentId) {
        // Your load code
    }
    @Override
    public boolean saveAssignment(DCONAssignment assignment) {
        // Your save code
    }
}