猿问

参数化类中的空构造函数

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


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


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


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


慕虎7371278
浏览 137回答 2
2回答

米脂

我可能没有很好地解释这一点,但类型C一次只能是一种类型。当你说 时C extends Chart,你限制了 C 可以是什么类型,但在一天结束时它只能是这些类型之一。换句话说,任何给定的 InteractiveChart 可能是 Chart 类型的 InteractiveChart 或 SimpleChart 类型的 InteractiveChart,但不能同时是两者。因此,正如所写的那样,您的第二个构造函数必须采用该确切类型。C extends Chart也不会意味着“扩展图表任何类”。它的意思是“一个特定的类,它恰好扩展了 Chart”。您会收到编译错误,因为构造函数需要一个类型为 C 的类,但您试图为它提供一个类型为 SimpleChart 的类。C 可能不是 SimpleChart。例如,它可能是一个图表或 SomeOtherChart。TL; DR:为了需要你的第二个构造“扩展图表任何类”,只需使用Chart代替C。:)public&nbsp;InteractiveChart(Chart&nbsp;chart)&nbsp;{&nbsp;..&nbsp;}问题解决了。当然,这带来了一个更好的问题,您真的需要在这里使用泛型吗?到目前为止,您还没有展示任何需要它的东西。

芜湖不芜

所以,据我了解,您的要求是:您有某种 GUI 构建器框架,出于某种不幸的原因,它只获取类名或Class<?>实例或诸如此类的东西,并使用无参数构造函数。对于此框架,您希望InteractiveChart<SimpleChart>图表为new SimpleChart().您还有其他代码可以从更大的灵活性中受益:您想InteractiveChart<C>为不同的图表类型创建实例,而不仅仅是SimpleChart.我有这个权利吗?这个问题,那么,是Java不会让你定义构造函数,这只是对InteractiveChart<SimpleChart>-任何构造函数InteractiveChart都必须应用到任意的 C-所以你要定义一个构造任意InteractiveChart<C>简单地假设这C是SimpleChart,这(我希望你会同意)不是在这里做出的一个很好的假设,也不是 Java 支持的假设。一个简单的解决方法是InteractiveChart<SimpleChart>为您的 GUI 构建器框架创建一个子类来实例化:public class SimpleInteractiveChart extends InteractiveChart<SimpleChart> {&nbsp; &nbsp; public SimpleInteractiveChart() {&nbsp; &nbsp; &nbsp; &nbsp; super(new SimpleChart());&nbsp; &nbsp; }}然后您的 GUI 构建器框架可以使用new SimpleInteractiveChart(),而您的其他代码仍然可以使用InteractiveChart<C>它想要的任何类型参数。
随时随地看视频慕课网APP

相关分类

Java
我要回答