Este es un problema desagradable, y es posible que el diseño sea simplemente malo.Heredó algunos malos genéricos de Java
Escribo un conjunto de componentes de gráficos simples (circular, barra & gráficos de líneas) y me estoy ahogando con algunos genéricos. De antemano, estoy seguro de que hay muchas API de Java para hacer exactamente lo que estoy tratando de hacer aquí (gráficos/informes/etc.), sin embargo, estoy interesado en esto como un problema general de genéricos; el hecho de que involucra gráficos & reportando componentes es trivial.
Cada tabla hereda de una clase base abstracta genérica Chart
:
public abstract class Chart<T extends ChartComponent>
{
private List<T> components;
// ...rest of the Chart class
}
La razón por la que tenemos T extends ChartComponent
es debido a que cada subclase gráfico se compone de 1+ llamados componentes de gráfico (barras, líneas , sectores de la gráfica, etc.):
public abstract class ChartComponent
{
private Color color;
// .. rest of ChartComponent class
}
public class PieWedge extends ChartComponent
{
double wedgeValue;
// ... rest of PieWedge class
}
poner este diseño en conjunto:
public class PieChart extends Chart<PieWedge>
{
// ... thus its list of ChartComponents is actually a List<PieWedge>
}
De esta forma, PieChart
no es genérico (ni debería serlo) y siempre es del tipo Chart<PieWedge>
.
Anteriormente tenía la misma configuración para gráficos de barras y líneas, que se definían como BarChart extends Chart<BarGroup>
y LineChart extends Chart<Line>
respectivamente (ya que un gráfico de barras consta de 1+ grupos de barras, y un gráfico de líneas consta de líneas 1+).
Ahora quiero abstraer los gráficos de barras y líneas aún más. Ambos cuadros se grafican contra un gráfico cartesiano (x, y) con ejes xey; esto es opuesto a un gráfico circular que no está trazado contra ninguno de esos ejes.
Lo ideal es que quería crear una nueva clase abstracta llamada CartesianChart
que se extendía Chart
, y luego tener BarChart
y LineChart
se extienden ambas CartesianChart
. Este nuevo CartesianChart
introduciría nuevas propiedades (xAxisLabel
, gridTurnedOn
, etc.) que lógicamente se aplican a los gráficos de barras/líneas, pero no a los gráficos circulares.
Además, para restringir CartesianChart
de modo que sólo podría tener chartComponents
de tipo BarGroup
o Line
(y no PieWedge
), me gustaría para crear un nuevo tipo de componente de tabla como CartesianComponent extends ChartComponent
, y luego tener BarGroup
/Line
extienden eso. Si lo hace, impediría código como el de la compilación:
LineChart lineChart = new LineChart();
lineChart.addLine(new PieWedge());
Desde Line
extiende CartesianComponent
, pero sólo se extiende PieWedge
ChartComponent
. Por lo tanto, antes de llegar a mi problema que tenemos la siguiente jerarquía de herencia:
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>
El problema de esta configuración es que tanto en BarChart
y LineChart
da un error del compilador quejan de que CartesianChart
no es genérico. Esto tiene mucho sentido, pero no estoy seguro de qué puedo hacer para solucionarlo.
Si trato de volver a definir CartesianChart
:
public abstract class CartesianChart<T extends CartesianComponent> extends Chart<CartesianComponent>
{
// ...
}
me sale "discordancia de tipo" errores de compilación a través de toda mi código gráfico de barras/línea. En cada instancia del error, indica que está esperando argumentos de tipo List<CartesianComponent>
pero en su lugar encontró List<BarGroup>
o List<Line>
y que no son sustitutos adecuados.
Afortunadamente, esta es una solución rápida en algún lugar de la definición de clase de CartesianChart
y/o CartesianComponent
. De lo contrario, tendré que volver a diseñar toda la biblioteca de gráficos. De cualquier manera, estoy interesado en todas las sugerencias, excepto como "Oye, ¿por qué no pruebas JFreeCharts o ...". Una vez más, estoy interesado en la solución aquí, ya que se relaciona con la solución de una amplia gama de problemas genéricos similares; el hecho de que esto implique informes/gráficos es trivial.
¡Gracias de antemano por cualquier ayuda!
¿Qué intenta lograr haciendo 'Chart' genérico? En otras palabras, ¿por qué no simplemente definir los componentes 'class Chart {private List; } '? –
'clase abstracta pública CartesianChart extends Chart '? –
digitaljoel
Gracias por las sugerencias aquí. Voy a probar ambas sugerencias aquí. Por favor, vea mi comentario debajo de la respuesta de @nicholas.hauschild sobre mi temor de que la ampliación del Diagrama no impida que las subclases hagan un gráfico donde T no extiende ChartComponent. –
IAmYourFaja