我如何在工厂 subclass 中使用 subclasses 来覆盖 superclass 工厂中的抽象 class?
How do I use subclasses in a factory subclass to override abstract class in a superclass factory?
我正在编写一个程序,需要对抽象对象 Assignment
的子 class 执行 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 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;
}
}
总而言之,抽象工厂处理加载作业的一些繁重工作。具体工厂处理它们特定的分配实现的细节class。问题是用具体参数覆盖抽象方法。那么问题来了,如何在抽象工厂中指定方法,在具体工厂中用具体的参数覆盖呢?
我解决了这个问题,解决方案是使抽象工厂通用
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;
}
}
混凝土厂
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;
}
}
JSYK:您不必覆盖 DCONAssignment
中的 getId
、setId
、getName
和 setName
方法。它们是从基础 class 继承而来的,您实际上并没有改变它们。
当您使用 @Override
时,您是在告诉编译器您 打算 您正在创建的方法将父 class 中的方法替换为新方法。这意味着您 期望 父 class 有一个具有相同名称和签名的方法。如果编译器查找但找不到具有相同名称和签名的方法,则会生成错误。 Eclipse 接受错误,检查您的代码,并为您提供有关如何解决问题的建议。
选项 1:public abstract boolean saveAssignment(Assignment assignment);
基础 class 定义了一个带有 Assignment
参数的方法。一个DCONAssignment
是-一个Assignment
,所以你可以简单地在派生的class中定义saveAssignment
方法来接受一个Assignment
,并传入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(<? extends Assignment> assignment);
在这里,您的基础 class 方法明确声明它将接受任何扩展 Assignment
的 class。您将在派生的 class 中覆盖它,并再次检查实际的 class 以验证它被赋予正确的 class.
@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");
}
}
选项 3:public <T extends Assignment> boolean saveAssignment(T assignment)
同样,这与选项 2 相同,但明确为模板类型指定名称 T
。
选项 4:看起来与选项 1 相同,除了方法是否在基础中声明为抽象(无方法体)class。
最简单的修复方法是使用选项 1 方法,使用 instanceof
检查参数是否确实是预期的类型,然后进行转换。
一种更结构化的方法是声明您的工厂 class 是基于模板的。
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
}
}
抽象工厂可以像以前一样实现任何常用方法来完成繁重的工作。
我正在编写一个程序,需要对抽象对象 Assignment
的子 class 执行 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 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;
}
}
总而言之,抽象工厂处理加载作业的一些繁重工作。具体工厂处理它们特定的分配实现的细节class。问题是用具体参数覆盖抽象方法。那么问题来了,如何在抽象工厂中指定方法,在具体工厂中用具体的参数覆盖呢?
我解决了这个问题,解决方案是使抽象工厂通用
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;
}
}
混凝土厂
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;
}
}
JSYK:您不必覆盖 DCONAssignment
中的 getId
、setId
、getName
和 setName
方法。它们是从基础 class 继承而来的,您实际上并没有改变它们。
当您使用 @Override
时,您是在告诉编译器您 打算 您正在创建的方法将父 class 中的方法替换为新方法。这意味着您 期望 父 class 有一个具有相同名称和签名的方法。如果编译器查找但找不到具有相同名称和签名的方法,则会生成错误。 Eclipse 接受错误,检查您的代码,并为您提供有关如何解决问题的建议。
选项 1:public abstract boolean saveAssignment(Assignment assignment);
基础 class 定义了一个带有 Assignment
参数的方法。一个DCONAssignment
是-一个Assignment
,所以你可以简单地在派生的class中定义saveAssignment
方法来接受一个Assignment
,并传入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(<? extends Assignment> assignment);
在这里,您的基础 class 方法明确声明它将接受任何扩展 Assignment
的 class。您将在派生的 class 中覆盖它,并再次检查实际的 class 以验证它被赋予正确的 class.
@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");
}
}
选项 3:public <T extends Assignment> boolean saveAssignment(T assignment)
同样,这与选项 2 相同,但明确为模板类型指定名称 T
。
选项 4:看起来与选项 1 相同,除了方法是否在基础中声明为抽象(无方法体)class。
最简单的修复方法是使用选项 1 方法,使用 instanceof
检查参数是否确实是预期的类型,然后进行转换。
一种更结构化的方法是声明您的工厂 class 是基于模板的。
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
}
}
抽象工厂可以像以前一样实现任何常用方法来完成繁重的工作。