参数化类中的构造函数为空



我有一个类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子类,用于固定泛型参数。我希望找到一种方法来消除这个子类,因为每次我添加一种新的Chart时,我也必须添加一个新的包装器来进行交互。

我可能没有很好地解释这一点,但类型C一次只能是单个类型。当你说C extends Chart时,你限制了C的类型,但归根结底,它只能是这些类型中的一种。换句话说,任何给定的交互图表都可能是Chart类型的交互图表或SimpleChart类型,但不能同时是两者。

因此,正如它所写的,您的第二个构造函数必须采用完全相同的类型。C extends Chart不是指"任何扩展Chart的类"。它的意思是"一个特定的类,它恰好扩展了Chart"。出现编译错误是因为构造函数需要一个C类型的类,但您试图为它提供一个SimpleChart类型的类。C可能不是SimpleChart。例如,它可能是一个图表,也可能是其他图表。

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

public InteractiveChart(Chart chart) { .. }

问题解决了。

当然,这带来了一个更好的问题,那就是你真的需要在这里使用泛型吗?到目前为止,你还没有展示任何需要它的东西。

所以,据我所知,您的需求是:

  • 您有某种GUI构建器框架,由于某种不幸的原因,它只获得类名或Class<?>实例或其他什么,并使用无参数构造函数。对于这个框架,您需要InteractiveChart<SimpleChart>,图表为new SimpleChart()
  • 您还有其他代码可以从更大的灵活性中获益:除了SimpleChart之外,您还想为不同的图表类型创建InteractiveChart<C>实例

我有这个权利吗?

那么,问题是Java不允许您定义仅用于InteractiveChart<SimpleChart>的构造函数—InteractiveChart的任何构造函数都必须应用于任意C—因此,您试图为任意InteractiveChart<C>定义一个构造函数,该构造函数只是假设CSimpleChart,这(我希望您同意(不是一个很好的假设,也不是Java支持的假设。

一个简单的解决方法是为GUI构建器框架创建InteractiveChart<SimpleChart>的子类以进行实例化:

public class SimpleInteractiveChart extends InteractiveChart<SimpleChart> {
public SimpleInteractiveChart() {
super(new SimpleChart());
}
}

然后,您的GUI构建器框架可以使用new SimpleInteractiveChart(),而您的其他代码仍然可以将InteractiveChart<C>与它想要的任何类型参数一起使用。

相关内容

  • 没有找到相关文章

最新更新