- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个子类列表,它们都是父类(super class)的实例。我的目标是创建一个工厂,它将根据子类返回不同的结果。
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 的情况下做到这一点?
更新。这里为了说明我要存档的是原代码:
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);
}
}
最佳答案
不幸的是,没有干净的方法来做到这一点,因为在编译期间我们不知道要调用哪个方法。为此,您可以使用 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);
}
}
}
示例用法:
public class Main {
public static void main(String[] args) throws Exception {
List<SuperClass> fields = Arrays.asList(new SubClass1(), new SubClass2(), new SubClass1());
for (SuperClass field : fields) {
System.out.println(FieldFactory.getViewFromPDField(new Context(), field));
}
}
}
以上打印:
TextBox
CheckBox
TextBox
当然这只是一个示例,您应该使用一些反射库或实用程序更好地实现它。我们假设每个 View
实现都有给定的构造函数等。
关于java - 工厂方法重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50031934/
假设我有一个类,我在其中重载了运算符 == : Class A { ... public: bool operator== (const A &rhs) const; ... };
我知道你不应该使用 std::find(some_map.begin(), some_map.end()) 或 std::lower_bound,因为它会采用线性时间而不是 some_map.lowe
我正在尝试在 Haskell 中定义 Vector3 数据类型,并允许在其上使用 (+) 运算符。我尝试了以下方法: data Vector3 = Vector3 Double Double Doub
我已经为我的类图将运算符重载为“-”。它的用途并不完全直观(糟糕的编码 - 我知道)但是如果我做 graph3 = graph2-graph1 那么图 3 是应该只接收图 2 和图 1 中的那些顶点。
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Operator overloading 我想重载 以按字母顺序排列字符串,但我不确定该怎么做。 如何再次
下面的代码给我一个编译错误。谁能告诉我为什么? class mytype { public: int value; mytype(int a) { value = a;
这有什么问题吗? class Vec2 attr_accessor :x, :y # ... def += (v) @x += v.x @y += v.y retu
是否可以重载 [] 运算符两次?允许这样的事情:function[3][3](就像在二维数组中一样)。 如果可能的话,我想看看一些示例代码。 最佳答案 您可以重载 operator[] 以返回一个对象
我的团队目前正在与 Lua 合作,创建一个 android 游戏。我们遇到的一件事是表面上无法创建重载构造函数。 我习惯于使用默认值设置一个对象,然后在需要时使其过载。 前任: apples() {
我有一个网页,在某个时候显示一个导航栏,它只不过是一个 a 元素的列表 (ul)。所述 a 元素的大多数样式规则都是通用的。唯一应该改变的部分是要显示的图像,可以从列表中每个 li 元素的 id 标签
我对使用/重载“范围步长”运算符(.. ..)很感兴趣,但我终其一生都无法了解如何使用它。 在文档中它说 // Usage: start .. step .. finish 但是在 F# shell
Java 11(可能无关紧要): public static String toString(Object obj) { return ReflectionToStringBuilder.to
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我无法理解以下代码(针对行号进行注释) class Base { void m1(Object o) { } void m2(String o) { } } publi
我有以下代码片段: #include using namespace std; struct Integer{ int x; Integer(const int val) : x(v
class myclass{ //definitions here }; myclass e; int myarray[10]; /* Do something... */ e = myarray;
为什么不能将下标运算符(operator [])作为 friend 函数重载? 最佳答案 正如Bjarne Stroustrup在D&E book中所说: However, even in the o
我有以下代码片段: #include using namespace std; struct Integer{ int x; Integer(const int val) : x(v
因此,我有一个问题是我最近尝试重载 namespace Eng { /** * A structure to represent pixels */ typedef
如何重载onResume()以正确的方式工作?我想从 activity 返回到 MainActivity ,我希望在其中具有与应用程序启动后相同的状态。我想使用 recreate() 但它循环了或者类
我是一名优秀的程序员,十分优秀!