首页 > 解决方案 > 参数化类中的空构造函数

问题描述

我有一个类InteractiveChart,它包装一个Chart(接口)并通过将用户交互映射到 setter 调用来为其添加交互性Chart

1)因为不同的子类Chart可以具有不同的“额外”功能,所以我希望在包装类中有一个 getter 来返回包装Chart(无需进行未经检查的强制转换!)。我知道这样做的唯一方法是在包装类上有一个通用参数。

2) 这个包装类也打算用在 NetBeans 的 GUI Builder 中,它的约束是它需要一个空的构造函数。但是,泛型参数的运行时类型由实例化它的代码决定,我无法控制 NetBeans 如何实例化它。在这种情况下,我希望它包装 a SimpleChart,如果用户想要包装其他东西,他们必须JPanel在 GUI 中添加一个占位符并将图表添加到用户代码中。由于相同的约束,我不能在包装类上使用通用参数。

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我希望找到一种方法来消除这个子类,因为每次我添加一种新的图表时,我都必须添加一个新的包装器来实现交互性。

标签: javagenericsgui-builder

解决方案


我可能没有很好地解释这一点,但类型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) { .. }

问题解决了。

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


推荐阅读