我目前正在使用以下类型:
// A Field whose values are of type V.
interface Field<V> {
public V getValue();
}
// A Field whose values are of type V and that has a LabelProvider for those values.
interface LabelField<V> extends Field<V> {
public LabelProvider<V> getLabelProvider();
}
这些来自图书馆,我无法改变它们。这可能不相关,但LabelProvider基本上是一个将V类型的值转换为字符串的类。
现在我想创建一个提供类似于此的接口的类:
// A Wrapper class for Fields of values V
interface IWrapper<V, F extends Field<V>> {
public F getField();
public V getValue();
public String getLabel();
}
该类将包装一个Field,并让其用户从该字段中检索该值,还提供其他功能,包括检索标签。这就是我所拥有的:
public class Wrapper<V, F extends Field<V>> {
private F field;
private LabelProvider<V> labelProvider; // Converts from V to String
// Since we have no guarantee that F has a LabelProvider, one is explicitely supplied.
public Wrapper(F field, LabelProvider<V> labelProvider) {
this.field = field;
this.labelProvider = labelProvider;
}
private String getLabel() {
return labelProvider.getLabel(field.getValue());
}
public F getField() {
return field;
}
public V getValue() {
return field.getValue();
}
}
直到这一点没问题,虽然我不确定我是否需要这两种通用类型。理想情况下,我希望只有Wrapper&gt;并且能够访问F和V.我认为这是不可能的,并且上述是正确的方法吗?
现在这是真正的问题。
我想为LabelField类型设置一个更具体的构造函数,如下所示:
public Wrapper(LabelField<V> labelField) {
// Use the field's own label provider
this(labelField, labelField.getLabelProvider());
}
在这种情况下,可以从字段中提取labelprovider。但编译器不喜欢这样,我得到以下错误:
The constructor Wrapper<V,F>(LabelField<V>, LabelProvider<V>) is undefined
即使这个使用相同类型的方法编译:
public static <X> void test(LabelField<X> lf) {
LabelProvider<X> lp = lf.getLabelProvider();
new Wrapper<X, LabelField<X>>(lf, lp);
}
为什么第二个构造函数不能编译?
这是一个SSCE:http://pastebin.com/UqLJhJA7
答案 0 :(得分:1)
F
可以是任何扩展Field<V>
的类型,而且该类型不一定是LabelField
。
例如,如果您创建实现FooField
的类Field<Object>
并使用Wrapper<Object, FooField>
,则LabelField
构造函数将不匹配。
您可以通过这种方式简化您的包装(这也可以回答您的第一点):
public class Wrapper<V> {
private Field<V> field;
private LabelProvider<V> labelProvider; // Converts from V to String
// Since we have no guarantee that F has a LabelProvider, one is explicitely
// supplied.
public Wrapper(Field<V> field, LabelProvider<V> labelProvider) {
this.field = field;
this.labelProvider = labelProvider;
}
public Wrapper(LabelField<V> labelField) {
// Use the field's own label provider
this(labelField, labelField.getLabelProvider());
}
private String getLabel() {
return this.labelProvider.getLabel(this.field.getValue());
}
public Field<V> getField() {
return this.field;
}
public V getValue() {
return this.field.getValue();
}
}
这使用“常规”多态而不是field
的泛型。
答案 1 :(得分:0)
你混合了泛型和继承。
您应该仅使用V
进行参数化:
public class Wrapper<V>
并写在下面
Field<V>
在你要写的所有地方
F