【发布时间】:2018-04-26 12:34:43
【问题描述】:
我有一个子类列表,它们都是 Super 类的实例。 我的目标是创建一个工厂,它会根据子类返回不同的结果。
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();
此代码将在编译期间失败,因为它需要 getInstance(SuperClass item) 重载,但如果我添加它,那么它总是会被调用。
有没有办法在不触及 SuperClass、SubClass1、SubClass2 的情况下做到这一点?
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);
}
}
【问题讨论】:
-
如果
item是SubClass3怎么办? -
public static getInstance(...) - 这甚至可以编译吗?返回类型呢?
-
Visitor Pattern 允许您以面向对象的方式执行此操作,但这涉及到
SuperClass和所有子类。否则,这意味着在Generator()中使用instanceof使用一堆if条件和强制转换来测试类型。 -
@JamesB 对不起,我没有尝试编译这个确切的代码,但我的代码是相似的。
标签: java overloading