工厂方法返回扩展两种类型的通用类型。

4
在这个工厂中,返回实现了特殊接口的Component,我遇到了错误“类型不匹配:无法从SpiffyCombo转换为C”在createSomethingSpiffy中。
我是做错了什么吗?还是说我必须在此处将SpiffyCombo转换为C
class Factory {
    public static <C extends Component & SpiffyComponent> C createSomethingSpiffy(Object... params) {
        C comp = new SpiffyCombo();
        // real method will be more complex
        return comp;
    }
}

class SpiffyTextField extends Component implements SpiffyComponent {
    public void wow() { ... }
}

class SpiffyCombo extends JComboBox implements SpiffyComponent {
    public void wow() { ... }
}

interface SpiffyComponent {
    void wow();
}

如果我们调用 SpiffyTextField foo = Factory.<SpiffyTextField>createSomethingSpiffy(),会发生什么? - Sotirios Delimanolis
@SotiriosDelimanolis 无法进行太多操作,因为在C comp = new SpiffyCombo()这一行出现了编译错误,在调用之前就已经出现了问题。此外,实际上,特定的返回类型将由传递给createSomethingSpiffy的参数确定。 - Brad Mace
这就是我的意思。编译器阻止你进入那个情况。 - Sotirios Delimanolis
将具体类型的值分配给类型参数变量是没有意义的,因为您不知道将绑定什么。 - Sotirios Delimanolis
@SotiriosDelimanolis 好的,也许我问错了。我们目前有一个createSomethingSpiffy方法,它接受一个数据库字段名称并返回适当类型的SpiffyComponent。我正在尝试修改它,以便我至少可以将结果用作Component而无需转换;获取确切的子类型甚至更好。 - Brad Mace
1个回答

0
类型参数仅从调用站点(+/-几个情况)真正有用。在类型参数的范围内,类型基本上是其边界。因此,尽管SpiffyCombo适合C的边界,但绑定到C的每种可能类型并不都是SpiffyCombo。因此,编译器不能让您互换使用它们的值。
您似乎想实现类似于
abstract class HellaSpiffyComponent extends Component implements SpiffyComponent {}

public static HellaSpiffyComponent createSomethingSpiffy(Object... params) {...}

并使您的相应类扩展HellaSpiffyComponent而不是扩展Component并实现SpiffyComponent


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接