java - 参数化类中的空构造函数
问题描述
我有一个类InteractiveChart
,它包装一个Chart
(接口)并通过将用户交互映射到 setter 调用来为其添加交互性Chart
。
1)因为不同的子类Chart
可以具有不同的“额外”功能,所以我希望在包装类中有一个 getter 来返回包装Chart
(无需进行未经检查的强制转换!)。我知道这样做的唯一方法是在包装类上有一个通用参数。
2) 这个包装类也打算用在 NetBeans 的 GUI Builder 中,它的约束是它需要一个空的构造函数。但是,泛型参数的运行时类型由实例化它的代码决定,我无法控制 NetBeans 如何实例化它。在这种情况下,我希望它包装 a SimpleChart
,如果用户想要包装其他东西,他们必须JPanel
在 GUI 中添加一个占位符并将图表添加到用户代码中。由于相同的约束,我不能在包装类上使用通用参数。
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之间的困境?
我目前最好的解决方案是创建一个固定泛型参数的InteractiveChart
被调用子类。InteractiveSimpleChart
我希望找到一种方法来消除这个子类,因为每次我添加一种新的图表时,我都必须添加一个新的包装器来实现交互性。
解决方案
我可能没有很好地解释这一点,但类型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) { .. }
问题解决了。
当然,这带来了一个更好的问题,你真的需要在这里使用泛型吗?到目前为止,您还没有展示任何需要它的东西。
推荐阅读
- javascript - 如何在 React 的每个页面上动态更改标题的道具?
- typescript - 获取嵌套 JSON 中键的所有值在 Lodash +Typescript 中不起作用
- amazon-web-services - 导入 dynamoose 后 3 秒后 AWS lambda 超时
- python - 给定该点的树索引,如何检索 kdtree 中某个点的坐标?
- php - 查看未从控制器 Laravel 8 接收变量
- javascript - 调用烧瓶 API 时不允许使用 POST 方法。确切的错误:POST http://127.0.0.1:5000/405(不允许的方法)
- javascript - 输入自动完成不适用于任何输入
- android - 使用导航组件的每个片段的自定义工具栏
- swift - Firebase pod 中的 Xcode 构建错误:错误:“FIRAuth”没有可见的@interface
- python - 为什么这个python Lark语法这么慢?