java - 参数化类中的空构造函数

标签 java generics gui-builder

我有一个类 InteractiveChart,它包装了 Chart(界面),并通过将用户交互映射到 Chart 上的 setter 调用来为其添加交互性。

1) 因为 Chart 的不同子类可以具有不同的“额外”功能,所以我希望在包装类中有一个 getter,它返回包装的 Chart (无需进行未经检查的强制转换!)。我知道做到这一点的唯一方法是在包装类上使用通用参数。

2) 此包装类还可以在 NetBeans 的 GUI Builder 中使用,它的限制是它需要一个空构造函数。然而,泛型参数的运行时类型是由实例化它的代码决定的,我无法控制 NetBeans 如何实例化它。在本例中,我希望它包装一个 SimpleChart,如果用户想要包装其他内容,他们必须向 GUI 添加一个 JPanel 占位符,并将图表添加到用户代码中。由于同样的限制,我不能在包装类上使用通用参数。

public class InteractiveChart<C extends Chart> extends JPanel {
    private final C wrappedChart;
    public InteractiveChart() {
        // Compiler error: at this point C can be any other subclass of Chart
        this(new SimpleChart()); 
    }

    public InteractiveChart(C chart) { wrappedChart = chart; }

    public C getWrappedChart() { return wrappedChart; }
}

如何解决1和2之间的困境?

我当前的最佳解决方案是创建一个名为 InteractiveSimpleChartInteractiveChart 子类,用于固定通用参数。我希望找到一种方法来消除这个子类,因为每次我添加一种新的图表时,我也必须添加一个新的包装器以实现交互性。

最佳答案

我可能没有很好地解释这一点,但是类型 C 一次只能是单一类型。当您说 C extends Chart 时,您限制了 C 的类型,但最终它只能是其中一种类型。换句话说,任何给定的 InteractiveChart 都可能是 Chart 类型的 InteractiveChart 或 SimpleChart 类型的 InteractiveChart,但不能同时是两者。

因此,正如所写,您的第二个构造函数必须采用该确切类型。 C extends Chart 确实表示“任何扩展 Chart 的类”。它的意思是“一个特定的类,它恰好扩展了 Chart”。您会收到编译错误,因为构造函数需要 C 类型的类,但您试图为其提供 SimpleChart 类型的类。 C 可能不是 SimpleChart。例如,它可能是图表,也可能是 SomeOtherChart。

TL;DR:为了在第二个构造函数中要求“任何扩展 Chart 的类”,您只需使用 Chart 而不是 C。 :)

public InteractiveChart(Chart chart) { .. }

问题已解决。

当然,这提出了一个更好的问题,即你真的需要在这里使用泛型吗?到目前为止,您还没有显示任何需要它的内容。

关于java - 参数化类中的空构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51637472/

相关文章:

java - 使用 New Relic 的 Spring Boot 无需修改依赖项

java - 在 Java 中与基于文本的游戏中的其他对象交互

generics - Swift - 通用类型类/结构的扩展?

java - 具有作为构造函数参数传递的通用基类的枚举

java - 我们可以在java swing中编辑生成的代码吗?

java - 如何使用 Swing 创建拖放组件 GUI 构建器?

java - 看似无限循环终止,除非使用 System.out.println

java - 如何在 JavaFX 项目中使用 KeyEvent?

swift - 泛型类型错误 : Cannot explicitly specialise a generic type

java - Swing JTable 黑客