Java 工厂方法重载
我有一个子类列表,这些子类都是超类的实例。 我的目标是创建一个工厂,它将根据子类返回不同的结果Java 工厂方法重载,java,overloading,Java,Overloading,我有一个子类列表,这些子类都是超类的实例。 我的目标是创建一个工厂,它将根据子类返回不同的结果 public class SuperClass { ... } public class SubClass1 extends SuperClass { ... } public class SubClass2 extends SuperClass { ... } public class Factory { public static getInstance(Su
public class SuperClass {
...
}
public class SubClass1 extends SuperClass {
...
}
public class SubClass2 extends SuperClass {
...
}
public class Factory {
public static getInstance(SubClass1 item) {
return new EditText();
}
public static getInstance(SubClass2 item) {
return new CheckBox();
}
}
public class Generator {
public Generator() {
List<SuperClass> list = getList();
for (SuperClass item : list) {
Factory.getInstance(item);
}
}
List<SuperClass> getList() {
...
}
}
new Generator();
公共类超类{
...
}
公共类子类1扩展了超类{
...
}
公共类子类2扩展了超类{
...
}
公营工厂{
公共静态getInstance(子类1项){
返回新的EditText();
}
公共静态getInstance(子类2项){
返回新复选框();
}
}
公共类生成器{
公共生成器(){
List=getList();
对于(超类项:列表){
Factory.getInstance(项目);
}
}
List getList(){
...
}
}
新发电机();
这段代码在编译过程中会失败,因为它需要getInstance(超类项)重载,但如果我添加它,它将始终被调用
有没有一种方法可以在不涉及超类、子类1、子类2的情况下做到这一点
UPD。为了澄清我想要归档的内容,这里是原始代码:
import android.content.Context;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RadioButton;
import com.tom_roush.pdfbox.cos.COSArray;
import com.tom_roush.pdfbox.cos.COSDictionary;
import com.tom_roush.pdfbox.cos.COSName;
import com.tom_roush.pdfbox.pdmodel.PDDocument;
import com.tom_roush.pdfbox.pdmodel.PDDocumentCatalog;
import com.tom_roush.pdfbox.pdmodel.PDPage;
import com.tom_roush.pdfbox.pdmodel.PDPageTree;
import com.tom_roush.pdfbox.pdmodel.common.PDRectangle;
import com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
import com.tom_roush.pdfbox.pdmodel.interactive.form.PDAcroForm;
import com.tom_roush.pdfbox.pdmodel.interactive.form.PDCheckbox;
import com.tom_roush.pdfbox.pdmodel.interactive.form.PDField;
import com.tom_roush.pdfbox.pdmodel.interactive.form.PDRadioButton;
import com.tom_roush.pdfbox.pdmodel.interactive.form.PDTextField;
public class Page {
private View view;
private Context context;
private PDDocument file;
public Page(Context _context, View _view, PDDocument _document) {
view = _view;
context = _context;
document = _document;
renderFields();
}
private void renderFields() {
PDDocumentCatalog docCatalog = document.getDocumentCatalog();
RelativeLayout ll = view.findViewById(R.id.pageFields);
ll.removeAllViews();
PDPageTree pageTree = docCatalog.getPages();
PDPage page = pageTree.get(pageIndex);
PDAcroForm acroForm = docCatalog.getAcroForm();
List<PDField> fields = acroForm.getFields();
for (PDField field : fields) {
String fieldName = field.getFullyQualifiedName();
COSDictionary fieldDict = field.getCOSObject();
COSArray fieldAreaArray = (COSArray) fieldDict.getDictionaryObject(COSName.RECT);
PDRectangle mediaBox = new PDRectangle(fieldAreaArray);
int fieldColor = Color.argb(180, 220, 228, 254);
// Factory
View fieldView = FieldFactory.getViewFromPDField(context, field);
RelativeLayout.LayoutParams fieldLayoutParams = new RelativeLayout.LayoutParams(
(int) (mediaBox.getWidth() * posRatio),
(int) (mediaBox.getHeight() * posRatio)
);
fieldLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
fieldLayoutParams.leftMargin = (int) (left * posRatio);
fieldLayoutParams.topMargin = (int) (top * posRatio);
fieldView.setBackgroundColor(fieldColor);
fieldView.setLayoutParams(fieldLayoutParams);
ll.addView(fieldView, fieldLayoutParams);
}
}
}
...
public class FieldFactory {
public static View getViewFromPDField(Context context, PDTextField field) {
return new EditText(context);
}
public static View getViewFromPDField(Context context, PDCheckbox field) {
return new CheckBox(context);
}
public static View getViewFromPDField(Context context, PDRadioButton field) {
return new RadioButton(context);
}
}
导入android.content.Context;
导入android.view.view;
导入android.widget.CheckBox;
导入android.widget.EditText;
导入android.widget.RadioButton;
导入com.tom_roush.pdfbox.cos.COSArray;
导入com.tom_roush.pdfbox.cos.cosdirectionary;
导入com.tom_roush.pdfbox.cos.COSName;
导入com.tom_roush.pdfbox.pdmodel.PDDocument;
导入com.tom_roush.pdfbox.pdmodel.PDDocumentCatalog;
导入com.tom_roush.pdfbox.pdmodel.PDPage;
导入com.tom_roush.pdfbox.pdmodel.PDPageTree;
导入com.tom_roush.pdfbox.pdmodel.common.PDRectangle;
导入com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
导入com.tom_roush.pdfbox.pdmodel.interactive.form.PDAcroForm;
导入com.tom_roush.pdfbox.pdmodel.interactive.form.PDCheckbox;
导入com.tom_roush.pdfbox.pdmodel.interactive.form.PDField;
导入com.tom_roush.pdfbox.pdmodel.interactive.form.PDRadioButton;
导入com.tom_roush.pdfbox.pdmodel.interactive.form.PDTextField;
公共类页面{
私人视野;
私人语境;
私人文件档案;
公共页面(上下文-上下文、视图-视图、PDDocument-文档){
视图=_视图;
上下文=_上下文;
文件=_文件;
renderFields();
}
私有void renderFields(){
PDDocumentCatalog docCatalog=document.getDocumentCatalog();
RelativeLayout ll=view.findViewById(R.id.pageFields);
ll.removeAllViews();
PDPageTree pageTree=docCatalog.getPages();
PDPage=pageTree.get(pageIndex);
PDAcroForm acroForm=docCatalog.getAcroForm();
列表字段=acroForm.getFields();
用于(PDField:字段){
字符串fieldName=field.getFullyQualifiedName();
COSDictionary fieldDict=field.getCOSObject();
COSArray fieldAreaArray=(COSArray)fieldDict.getDictionaryObject(COSName.RECT);
PDRectangle mediaBox=新的PDRectangle(fieldAreaArray);
int fieldColor=Color.argb(180220228254);
//工厂
View fieldView=FieldFactory.getViewFromPDField(上下文,字段);
RelativeLayout.LayoutParams fieldLayoutParams=新的RelativeLayout.LayoutParams(
(int)(mediaBox.getWidth()*posRatio),
(int)(mediaBox.getHeight()*posRatio)
);
fieldLayoutParams.addRule(RelativeLayout.ALIGN\u PARENT\u LEFT);
fieldLayoutParams.leftMargin=(int)(左*正比例);
fieldLayoutParams.topMargin=(int)(top*posRatio);
fieldView.setBackgroundColor(fieldColor);
fieldView.setLayoutParams(fieldLayoutParams);
ll.addView(fieldView,fieldLayoutParams);
}
}
}
...
公营工厂{
公共静态视图getViewFromPDField(上下文,PDTextField){
返回新的编辑文本(上下文);
}
公共静态视图getViewFromPDField(上下文上下文,PDCheckbox字段){
返回新复选框(上下文);
}
公共静态视图getViewFromPDField(上下文上下文,PDRadioButton字段){
返回新单选按钮(上下文);
}
}
相反,将超类
抽象化,并添加一个新的实例方法,该方法实现您所寻找的功能,每个子类用其不同的行为覆盖它:
public abstract class SuperClass {
public abstract View getView(Context context);
}
public class SubClass1 extends SuperClass {
@Override
public View getView(Context context) {
...
}
}
不幸的是,没有干净的方法可以做到这一点,因为在编译时,我们不知道调用哪个方法。为此,您可以使用
instanceof
关键字或使用反射
假设您的模型大致如下所示:
class SuperClass {
//...
}
class SubClass1 extends SuperClass {
//...
}
class SubClass2 extends SuperClass {
//...
}
class Context {
//...
}
abstract class View {
private final Context context;
public View(Context context) {
this.context = context;
}
@Override
public String toString() {
return getClass().getSimpleName();
}
}
class TextBox extends View {
public TextBox(Context context) {
super(context);
}
}
class CheckBox extends View {
public CheckBox(Context context) {
super(context);
}
}
class FieldFactory {
static Map<Class<? extends SuperClass>, Class<? extends View>> fieldEditorMap = new HashMap<>();
static {
fieldEditorMap.put(SubClass1.class, TextBox.class);
fieldEditorMap.put(SubClass2.class, CheckBox.class);
}
public static View getViewFromPDField(Context context, SuperClass field) {
Class<? extends View> editorClass = fieldEditorMap.get(field.getClass());
try {
return editorClass.getConstructor(Context.class).newInstance(context);
} catch (Exception e) {
throw new IllegalArgumentException("Can not create view for " + field.getClass().getSimpleName(), e);
}
}
}
您可以按如下方式实现factory:
class SuperClass {
//...
}
class SubClass1 extends SuperClass {
//...
}
class SubClass2 extends SuperClass {
//...
}
class Context {
//...
}
abstract class View {
private final Context context;
public View(Context context) {
this.context = context;
}
@Override
public String toString() {
return getClass().getSimpleName();
}
}
class TextBox extends View {
public TextBox(Context context) {
super(context);
}
}
class CheckBox extends View {
public CheckBox(Context context) {
super(context);
}
}
class FieldFactory {
static Map<Class<? extends SuperClass>, Class<? extends View>> fieldEditorMap = new HashMap<>();
static {
fieldEditorMap.put(SubClass1.class, TextBox.class);
fieldEditorMap.put(SubClass2.class, CheckBox.class);
}
public static View getViewFromPDField(Context context, SuperClass field) {
Class<? extends View> editorClass = fieldEditorMap.get(field.getClass());
try {
return editorClass.getConstructor(Context.class).newInstance(context);
} catch (Exception e) {
throw new IllegalArgumentException("Can not create view for " + field.getClass().getSimpleName(), e);
}
}
}
当然,这只是一个示例,您应该使用一些反射库或UTIL更好地实现它。我们假设每个视图
实现都提供了构造函数等。我喜欢的是的解决方案,并希望使用扩展它
使用泛型背后的理由是要有一个单一的、通用的实现,以后可以用于多种任务
我已将原来的解决方案修改为通用解决方案。工厂现在必须实例化,因为它是泛型的,实例化为我们选择的特定类提供了特定工厂
为了编译和运行以下代码,我使用了我的选择:
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
public class MyClass {
static class SuperClass {
//tagging
}
static class SubClass1 extends SuperClass {
//
}
static class SubClass2 extends SuperClass {
//...
}
static class Context {
//...
}
static abstract class View {
private final Context context;
public View(Context context) {
this.context = context;
}
@Override
public String toString() {
return getClass().getSimpleName();
}
}
static class TextBox extends View {
public TextBox(Context context) {
super(context);
}
}
static class CheckBox extends View {
public CheckBox(Context context) {
super(context);
}
}
static class Pair<P0,P1> {
public P0 p0;
public P1 p1;
public Pair(P0 p0, P1 p1) {
this.p0 = p0;
this.p1 = p1;
}
}
static class FieldFactory<T extends SuperClass, P extends View> {
Map<Class<T>, Class<P>> fieldEditorMap = new HashMap<>();
public FieldFactory(List<Pair<Class<T>, Class<P>>> boundClassMapping){
boundClassMapping.stream().forEach(pair -> fieldEditorMap.put(pair.p0,pair.p1));
}
public P getViewFromPDField(Context context, T field) {
Class<P> editorClass = fieldEditorMap.get(field.getClass());
try {
return editorClass.getConstructor(Context.class).newInstance(context);
} catch (Exception e) {
throw new IllegalArgumentException("Can not create view for " + field.getClass().getSimpleName(), e);
}
}
}
public static void main(String args[]) {
List<Pair<Class<? extends SuperClass>, Class<? extends View>>> mapping = new ArrayList<>();
mapping.add(new Pair<Class<? extends SuperClass>, Class<? extends View>>(SubClass1.class, TextBox.class));
mapping.add(new Pair<Class<? extends SuperClass>, Class<? extends View>>(SubClass2.class, CheckBox.class));
FieldFactory ff = new FieldFactory(mapping);
List<SuperClass> fields = Arrays.asList(new SubClass1(), new SubClass2(), new SubClass1());
for (SuperClass field : fields) {
System.out.println(ff.getViewFromPDField(new Context(), field));
}
}
}
如果
项
是子类3
,该怎么办?公共静态getInstance(…)-这甚至可以编译吗?返回类型如何?使用泛型如何?允许您以面向对象的方式执行此操作,但这涉及到触摸超类
和所有子类。否则,它意味着在Generator()
中使用instanceof
测试类型,使用一系列if
条件和强制类型转换。@JamesB很抱歉,我没有尝试编译这个确切的代码,但我的代码类似。我只是提出了一个使用反射的想法。我不想把事情复杂化
TextBox
CheckBox
TextBox