java - 如何使用对象的原始类来转换引用?

标签 java casting processing

我正在开发一个用于处理的 GUI 库,并且我有一个类 Component。我有很多其他扩展 Component 的类:LabelButton(扩展了 Label)、面板图标。这些类仅继续“逻辑”部分(位置、文本、功能检查是否被单击等...)。

Panel内部有一个ComponentArrayList,您可以向其中添加按钮、标签等...

为了显示组件,我决定使用类 Theme,它内部有函数 display(Component component) 的一些重载(一个用于 Label,一个用于 Button,一个用于 Panel 等...)。

display(Panel panel) 内部,在某些时候,我会显示面板的所有子项,但是,不是将它们(子项)视为 ButtonLabel,它将它们全部视为Component。我该如何解决这个问题?

  1. 我已经尝试在 ComponentButton 等类中使用 display() 方法...部分有效,但它带来了一些“编码问题”:要覆盖函数显示,您必须创建一个新类(示例:GreenBackgroundButton 扩展 Button{})。另外,通过将所有函数放在外部类中,您可以使用单个类来控制程序的所有图形,因此您可以使用单个函数 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);
}

我希望在 Canvas 上看到面板内的工作按钮,而不是看到组件。我现在没有任何具体的错误。

最佳答案

使用 instanceof 几乎总是一种黑客行为,并且可能是糟糕设计的症状。

您所描述的内容听起来与名为 Abstract Window Toolkit 的现有 Java 库完全相同。 (AWT),因此您可能会考虑“借用”他们的一些设计模式。

  • Component 是一个抽象类,它定义了一个抽象 paint() 函数。 paint() 函数采用 Graphics 参数。稍后会详细介绍。
  • ButtonLabel 扩展 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 类中并没有带来巨大的好处。我可能会将所有内容直接放入我的组件子类中,例如 ButtonLabel

关于java - 如何使用对象的原始类来转换引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56209691/

相关文章:

javascript - 当一个数字上升时如何降低另一个数字?

Java 菱形运算符无法编译

casting - TypeScript:类型中缺少索引签名

c++ - 为什么从指向基的指针到指向派生的指针的 static_cast 是 "invalid?"

将 long 转换为 (void *) 以传递

java - 线路旋转: Processing

java - 像MS Paint一样画直线

java - 在 Java 中注释多行的语法是什么?

java - 如何检查一个区间是否包含2的幂

java - 排序后,如何在 Netbeans swing 大纲(树表)中保持搜索结果一致?