繁体   English   中英

如何使用对象的原始 class 投射引用?

[英]How to cast a reference with an object's original class?

我正在开发一个用于处理的 GUI 库,并且我有一个 class Component 我有一堆其他类扩展ComponentLabelButton (扩展Label ), PanelIcon 这些类仅继续“逻辑”部分(位置、文本、function 检查它们是否被单击等......)。

class Panel内部有一个ArrayListComponent ,您可以添加按钮、标签等...

为了显示组件,我决定使用 class Theme ,其中包含Button display(Component component)的一些重载(一个用于Label等...,一个用于Panel )。

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

  1. 我已经尝试在ComponentButton等类中使用方法display() ......它部分工作,但它给出了一些“编码问题”:要覆盖 function 显示,您必须创建一个新的 class (例如: GreenBackgroundButton 扩展了 Button{})。 Also, by putting all the function in an external class, you can control all the grapihcs of you Program with a single class, so you can have the same background for all the components with a single function displayBackground() etc...

  2. 不能使用instanceof ,因为如果我必须使用它来投射面板的子项,则用户无法创建自定义组件,因为它们将显示为Component而不是TextField (示例)。

  3. 我已经尝试直接投射display((Button)panel.getChildren.get(0)) ,但是,当我使用 label 时,它会给出错误(如预期的那样)。

  4. 我也尝试过这样的投射: panel.getChildren().get(0).getClass().cast(panel.getChildren().get(0)) ,它不起作用,我不知道为什么。 (我尝试了它的所有变体,比如创建一个外部 object 等......)

  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几乎总是一种 hack,并且可能是糟糕设计的征兆。

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

  • Component是一个抽象的 class,它定义了一个抽象的paint() function。 paint() function 采用Graphics参数。 稍后会详细介绍。
  • ButtonLabel扩展Component并覆盖paint() function。
  • Graphics是一个 class ,其中包含drawRect()setBackground()等函数。 它封装了共享绘图代码,类似于我认为您的Theme class 会做的事情。

如果我是你,我会考虑为你的图书馆采取类似的方法。

我将尝试解决您的其他一些评论:

示例:GreenBackgroundButton 扩展 Button{}

对于这种情况,优先考虑 inheritance 的组合 您不需要扩展Button来设置背景。 相反,在Button() class (或在Component类)中有一个setBackground() function。

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 class。

另外,退后一步,我会鼓励您避免过度设计解决方案的诱惑。 您可能认为您需要一个复杂的设计,其中包含多个级别的 inheritance 和许多不同的类,但很可能一个更简单的设计可能会为您提供几乎所有您需要的东西。 具体来说,我认为将任何代码提取到Theme class 中没有巨大的好处。 我可能会将所有内容直接放在我的组件子类中,例如ButtonLabel

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM