我有一个类InteractiveChart
,该类包装了Chart
(接口)并通过将用户交互映射到Chart
上的setter调用来向其添加交互性。
1)因为Chart
的不同子类可以具有不同的'extra'功能,所以我希望包装类中有一个吸气剂,该吸气剂返回包装的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之间的难题?
我当前的最佳解决方案是创建一个称为
InteractiveChart
的InteractiveSimpleChart
子类,该子类可修复通用参数。我希望找到一种消除该子类的方法,因为每次添加一种新的Chart时,我也必须添加一个新的包装来实现交互性。 最佳答案
我可能无法很好地解释这一点,但是类型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) { .. }
问题解决了。
当然,这提出了一个更好的问题,您真的需要在这里使用泛型吗?到目前为止,您还没有显示任何需要它的东西。