我正在开发一个用于处理的 GUI 库,并且我有一个类 Component
。我有很多其他扩展 Component
的类:Label
、Button
(扩展了 Label
)、面板
和图标
。这些类仅继续“逻辑”部分(位置、文本、功能检查是否被单击等...)。
类Panel
内部有一个Component
的ArrayList
,您可以向其中添加按钮、标签等...
为了显示组件,我决定使用类 Theme
,它内部有函数 display(Component component)
的一些重载(一个用于 Label
,一个用于 Button
,一个用于 Panel
等...)。
在 display(Panel panel)
内部,在某些时候,我会显示面板的所有子项,但是,不是将它们(子项)视为 Button
或Label
,它将它们全部视为Component
。我该如何解决这个问题?
我已经尝试在
Component
、Button
等类中使用display()
方法...部分有效,但它带来了一些“编码问题”:要覆盖函数显示,您必须创建一个新类(示例:GreenBackgroundButton 扩展 Button{})。另外,通过将所有函数放在外部类中,您可以使用单个类来控制程序的所有图形,因此您可以使用单个函数displayBackground()
为所有组件提供相同的背景> 等等...instanceof
无法使用,因为如果我必须使用它来转换面板的子项,用户将无法创建自定义组件,因为它们将被显示作为Component
而不是TextField
(示例)。我尝试直接转换
display((Button)panel.getChildren.get(0))
,但是,正如它应该的那样,当我使用标签时,它会给出错误(如预期)。我也尝试过这样的转换:
panel.getChildren().get(0).getClass().cast(panel.getChildren().get(0))
,而且不起作用,我不知道为什么。 (我尝试了它的所有变体,例如创建外部对象等...)如果您需要更多代码,可以询问...
public void display(Panel panel) {
println("panel");
if (panel.isVisible()) {
pushMatrix();
translate(panel.getX(), panel.getY());
displayBackground(panel, #AAAAAA);
for (int i = 0; i < panel.getChildren().size(); i++) {
this.display(panel.getChildren().get(i).getClass().cast(panel.getChildren().get(i))); //THIS IS THE LINE WITH THE ISSUE
//println(panel.getChildren().get(i).getClass().cast(panel.getChildren().get(i)));
}
popMatrix();
}
}
Theme basicTheme;
Button close;
Panel panel;
void settings() {
size(400, 600, P2D);
}
void setup() {
basicTheme = new Theme();
close = new Button();
close.setBounds(10, 10, 100, 25);
close.setText("close");
panel = new Panel();
panel.setBounds(50, 200, 200, 200);
panel.add(close);
}
void draw() {
background(255);
basicTheme.display(panel);
}
我希望在 Canvas 上看到面板内的工作按钮,而不是看到组件。我现在没有任何具体的错误。
最佳答案
使用 instanceof
几乎总是一种黑客行为,并且可能是糟糕设计的症状。
您所描述的内容听起来与名为 Abstract Window Toolkit 的现有 Java 库完全相同。 (AWT),因此您可能会考虑“借用”他们的一些设计模式。
Component
是一个抽象类,它定义了一个抽象paint()
函数。paint()
函数采用Graphics
参数。稍后会详细介绍。Button
和Label
扩展Component
并覆盖paint()
函数。Graphics
是一个包含drawRect()
和setBackground()
等函数的类。它封装了共享绘图代码,类似于我认为您的Theme
类会做的事情。
如果我是您,我会考虑对您的图书馆采取类似的方法。
我会尝试解决您的其他一些评论:
Example: GreenBackgroundButton extends Button{}
喜欢composition over inheritance对于这样的情况。您不需要扩展 Button
来设置背景。相反,请在 Button()
类(或 Component
类)中使用 setBackground()
函数。
Also, by putting all the function in an external class, you can control all the rapihcs of you Program with a single class, so you can have the same background for all the components with a single function displayBackground() etc.
听起来这属于您的 Component
类。
此外,退一步来说,我鼓励您避免 over-engineer 的诱惑。一个办法。您可能认为您需要一个具有多个继承级别和许多不同类的复杂设计,但很可能一个更简单的设计可能会为您提供几乎所有您需要的东西。具体来说,我认为将任何代码提取到 Theme
类中并没有带来巨大的好处。我可能会将所有内容直接放入我的组件子类中,例如 Button
和 Label
。
关于java - 如何使用对象的原始类来转换引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56209691/