继承了一些糟糕的Java泛型

IAm*_*aja 6 java generics

这是一个令人讨厌的问题,可能是设计很糟糕.

编写一组简单的图表组件(饼图,条形图和折线图),并对一些泛型的东西窒息.事先,我确信有很多Java API可以完成我在这里尝试做的事情(图表/报告/等等),但我对此感兴趣是一般的泛型问题; 它涉及图表和报告组件的事实是微不足道的.

每个图表都继承自一个通用的抽象基类Chart:

public abstract class Chart<T extends ChartComponent>
{
    private List<T> components;

    // ...rest of the Chart class
}
Run Code Online (Sandbox Code Playgroud)

我们之所以这样,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
}
Run Code Online (Sandbox Code Playgroud)

把这个设计放在一起:

public class PieChart extends Chart<PieWedge>
{
    // ... thus its list of ChartComponents is actually a List<PieWedge>
}
Run Code Online (Sandbox Code Playgroud)

这样,PieChart不是通用的(也不应该是)并且始终是类型Chart<PieWedge>.

我以前有用于条形图和折线图,其被定义为相同的设置BarChart extends Chart<BarGroup>LineChart extends Chart<Line>分别(因为条形图由1+组的条,和一个线路图包括1+线).

现在我想进一步抽象出条形图和折线图.这两个图表实际上是针对具有x轴和y轴的(x,y)笛卡尔图绘制的; 这与未绘制任何此类轴的饼图相反.

理想情况下,我想创造一个新的名为抽象类CartesianChart,其扩展Chart,然后还要BarChartLineChart两个扩展CartesianChart.这种新的CartesianChart将引入新的属性(xAxisLabel,gridTurnedOn,等)逻辑适用于条形图/线形图,但不能饼图.

此外,为了限制CartesianChart它只能有chartComponents类型BarGroupLine(而不是PieWedge),我想创建一个新的图表组件类型CartesianComponent extends ChartComponent,然后具有BarGroup/ Line扩展它.这样做会阻止这样的代码编译:

LineChart lineChart = new LineChart();
lineChart.addLine(new PieWedge());
Run Code Online (Sandbox Code Playgroud)

由于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>
Run Code Online (Sandbox Code Playgroud)

这个设置的问题是两者都有,BarChart并且LineChart它给出了编译器错误,抱怨CartesianChart不是通用的.这完全有道理,但我不确定我能做些什么来修复它!

如果我尝试重新定义CartesianChart:

public abstract class CartesianChart<T extends CartesianComponent> extends Chart<CartesianComponent>
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

我通过条形码/折线图代码得到"类型不匹配"编译器错误.在错误的每个实例中,它声明它期望类型的参数,List<CartesianComponent>而是找到List<BarGroup>或者List<Line>它们不是合适的替代品.

希望这是一个快速修复类CartesianChart和/或类的定义CartesianComponent.否则我可能不得不重新设计整个图表库.无论哪种方式,我对任何和所有建议感兴趣,除了 " 嘿,你为什么不尝试JFreeCharts或 ......".同样,我对这里的解决方案感兴趣,因为它与解决各种类似的泛型问题有关; 这涉及报告/图表的事实是微不足道的.

在此先感谢您的帮助!

nic*_*ild 4

你的Chart类包含List<T>你所说的,所以当你定义你的CartesianChart抽象类来扩展时Chart<CartesianComponent>,你是在说那List<T>是真的List<CartesianComponent>

实际上,您想要的只是使用您在抽象类中定义的泛型(即<T extends CartesianComponent>)。我会尝试这样做,看看效果如何。

public abstract class CartesianChart<T extends CartesianComponent> extends Chart<T>
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)