这是一个令人讨厌的问题,可能是设计不好。
编写一组简单的图表组件(饼图,条形图和折线图),并在某些通用名称上感到窒息。事先,我确定有很多Java API可以准确地执行我在此处尝试执行的操作(图表/报告/等),但是,作为通用的泛型问题,我对此很感兴趣。它涉及图表和报表组件的事实是微不足道的。
每个图表都继承自通用抽象基类Chart
:
public abstract class Chart<T extends ChartComponent>
{
private List<T> components;
// ...rest of the Chart class
}
之所以使用
T extends ChartComponent
,是因为每个图表子类都将包含1个以上的所谓图表组件(条形,线形,楔形等):public abstract class ChartComponent
{
private Color color;
// .. rest of ChartComponent class
}
public class PieWedge extends ChartComponent
{
double wedgeValue;
// ... rest of PieWedge class
}
将此设计放在一起:
public class PieChart extends Chart<PieWedge>
{
// ... thus its list of ChartComponents is actually a List<PieWedge>
}
这样,
PieChart
不是通用的(也不应该是),并且始终为Chart<PieWedge>
类型。我以前对条形图和折线图有相同的设置,分别定义为
BarChart extends Chart<BarGroup>
和LineChart extends Chart<Line>
(因为条形图由1+组条形图组成,而折线图由1+线组成)。现在,我想进一步提取条形图和折线图。实际上,这两个图表都是针对具有x轴和y轴的(x,y)笛卡尔图绘制的;这与不针对任何此类轴绘制的饼图相反。
理想情况下,我想创建一个新的名为
CartesianChart
的抽象类,该类扩展了Chart
,然后让BarChart
和LineChart
都扩展了CartesianChart
。此新的CartesianChart
将引入新的属性(xAxisLabel
,gridTurnedOn
等),这些属性在逻辑上适用于条形图/折线图,而不适用于饼图。此外,为了限制
CartesianChart
使其仅具有chartComponents
或BarGroup
类型的Line
(而不是PieWedge
),我想创建一个像CartesianComponent extends ChartComponent
这样的新图表组件类型,然后让BarGroup
/Line
扩展该类型。这样做会阻止这样的代码编译:LineChart lineChart = new LineChart();
lineChart.addLine(new PieWedge());
由于
Line
扩展了CartesianComponent
,但是PieWedge
仅扩展了ChartComponent
。因此,在解决我的问题之前,我们具有以下继承层次结构:Chart
CartesianChart
BarChart
LineChart
PieChart
ChartComponent
CartesianComponent
BarGroup
Line
PieWedge
PieChart extends Chart<PieWedge>
CartesianChart extends Chart<CartesianComponent>
BarGroup extends CartesianComponent
Line extends CartesianComponent
BarChart extends CartesianChart<BarGroup>
LineChart extends CartesianChart<Line>
这种设置的问题在于,在
BarChart
和LineChart
上,它都会出现编译器错误,提示CartesianChart
不是通用的。 这完全有道理,但是我不确定该如何解决! 如果我尝试重新定义
CartesianChart
:public abstract class CartesianChart<T extends CartesianComponent> extends Chart<CartesianComponent>
{
// ...
}
我的条形图/折线图代码都出现“类型不匹配”的编译器错误。在该错误的每个实例中,它都声明它期望使用
List<CartesianComponent>
类型的参数,但是找到了List<BarGroup>
或List<Line>
,因此它们不是合适的替代品。希望这是
CartesianChart
和/或CartesianComponent
的类定义中的某个快速修复。否则,我可能不得不重新设计整个图表库。无论哪种方式,我都对的任何建议都感兴趣,除了之类的建议,例如“嘿,为什么不尝试JFreeCharts或...”。同样,我对这里的解决方案感兴趣,因为它与解决各种相似的泛型问题有关。这涉及报告/图表编制的事实是微不足道的。在此先感谢您提供的所有帮助!
最佳答案
您的Chart
类包含您所说的List<T>
,因此,当您定义CartesianChart
抽象类以扩展Chart<CartesianComponent>
时,您是在说List<T>
实际上是List<CartesianComponent>
。
确实,您想要的只是使用您在抽象类(即<T extends CartesianComponent>
)中定义的泛型。我会尝试这样做,看看效果如何。
public abstract class CartesianChart<T extends CartesianComponent> extends Chart<T>
{
// ...
}