java - 如何使用对象的原始类转换引用?
问题描述
我正在开发一个用于处理的 GUI 库,并且我有一个类Component
. 我有一堆其他类扩展Component
:Label
,Button
(扩展Label
)Panel
和Icon
。这些类仅包含“逻辑”部分(位置、文本、功能检查是否被单击等)。
这个类Panel
里面有一个ArrayList
of Component
,你可以给它添加按钮、标签等......
为了显示组件,我决定使用一个类Theme
,其中包含一些函数的重载display(Component component)
(一个用于Label
,一个用于Button
,一个用于Panel
等......)。
在内部display(Panel panel)
,在某些时候,我会显示面板的所有子项,但是,将它们(子项)视为Button
or Label
,它将所有子项视为Component
。我该如何解决这个问题?
1)我已经尝试display()
在类Component
中使用方法Button
等......它部分工作,但它给出了一些“编码问题”:要覆盖函数显示,您必须创建一个新类(例如:GreenBackgroundButton extends Button {})。此外,通过将所有功能放在外部类中,您可以使用单个类控制程序的所有 rapihcs,因此您可以使用单个功能等所有组件具有相同的背景displayBackground()
......
2)instanceof
不能使用,因为如果我必须使用它来转换面板的子级,用户无法创建自定义组件,因为它们会显示为Component
不像TextField
(示例)。
3)我试过直接投射display((Button)panel.getChildren.get(0))
,但是,因为它显示,当我使用标签时,它会给出一个错误(如预期的那样)。
4)我也尝试过这样的投射:panel.getChildren().get(0).getClass().cast(panel.getChildren().get(0))
,但它不起作用,我不知道为什么。(我尝试了它的所有变体,比如创建一个外部对象等......)
5)如果你需要更多的代码,你可以问...
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);
}
我希望在画布上看到面板内的工作按钮,而不是看到组件。我没有任何我现在能想到的特定错误。
解决方案
使用instanceof
几乎总是一种 hack,并且可能是糟糕设计的征兆。
您所描述的内容听起来与一个名为Abstract Window Toolkit (AWT) 的现有 Java 库完全一样,因此您可能会考虑“借用”它们的一些设计模式。
Component
是定义抽象paint()
函数的抽象类。该paint()
函数接受一个Graphics
参数。稍后会详细介绍。Button
并Label
扩展Component
和覆盖该paint()
功能。Graphics
是一个包含 和 之类的函数的drawRect()
类setBackground()
。它封装了共享绘图代码,类似于我认为您的Theme
课程会做的事情。
如果我是你,我会考虑为你的图书馆采取类似的方法。
我将尝试解决您的其他一些评论:
示例:GreenBackgroundButton 扩展 Button{}
在这种情况下,优先考虑组合而不是继承。您不需要扩展Button
来设置背景。相反,在类(或类)中有一个setBackground()
函数。Button()
Component
此外,通过将所有函数放在外部类中,您可以使用单个类控制程序的所有 rapihcs,因此您可以使用单个函数 displayBackground() 等为所有组件具有相同的背景。
听起来这属于你的Component
班级。
另外,退后一步,我会鼓励您避免过度设计解决方案的诱惑。您可能认为您需要一个具有多个继承级别和许多不同类的复杂设计,但很可能一个更简单的设计可能会为您提供几乎所有您需要的东西。具体来说,我没有看到将任何代码提取到Theme
类中的巨大好处。我可能会将所有内容直接放在我的组件子类中,例如Button
and Label
。
推荐阅读
- javascript - 在数组中添加星号?
- regex - 如何在 Sublime 3 中以连续的方式在许多相关文件上自动增加/添加/重新编号?
- android - PC 崩溃后 Android Studio 出现错误
- java - 设置属性“java.io.tmpdir”会导致测试失败
- ruby-on-rails - Rails 脚手架关联 has_many 错误:1 个错误禁止保存此产品
- php - 我的代码有什么问题?我在调用未定义的方法 mysqli::error() 时出错
- php - 尝试使用 ErrorDocument 处理请求时遇到 403 禁止错误。PHP 声音
- html - 为什么这个导航栏不会显示在其他所有内容之上?
- html - Bootstrap 'row' 类不适用于 CDN 或下载版本
- java - 如果我只需要通过套接字发送 1 个字节,我可以只使用一个字符吗?