Java 7
我有一个界面:
public interface MyInt{
public Map<String, WhereClause> createClauses(Parameters<Object> params);
}
及其实施:
public class MyImpl implements MyInt{
@Override
public Map<String, WhereClause> createClauses(Parameters<Object> p) { //1
//return some
}
}
现在,我可以将其返回类型设为通用。我试过这个:
public interface MyInt <T extends SomeType>{
public Map<String, ? extends WhereClause> createClauses(Parameters<Object> params);
}
但是我在//1
的实现中遇到了编译时错误:
The method createClauses(Parameters<Object>) of type `MyImpl` must
override or implement a supertype method
但是当我删除Generification时,实现编译得很好。
为什么即使不使用type parameter
,泛化也会影响编译。
答案 0 :(得分:5)
几乎在所有情况下,当你发现自己在泛型中使用?
时,你做错了:
public interface MyInt<C extends WhereClause> {
public Map<String, C> createClauses(Parameters<Object> params);
}
private static class MyWhereClause extends WhereClause {
public MyWhereClause() {
}
}
public class MyImpl implements MyInt<MyWhereClause> {
@Override
public Map<String, MyWhereClause> createClauses(Parameters<Object> p) {
return null;
}
}
答案 1 :(得分:1)
通常,当以主要方式修改界面时,例如,更改其类型参数,如果不重构,则所有子类型应立即中断。
但是有一个例外 - 如果一个接口没有使用任何泛型,我们可以添加泛型并仍然保持以前写的子类型兼容。当然,这是“迁移兼容性”。这是一个奇迹,它运作顺利;像Collection
这样的核心API在没有破坏旧程序的情况下被普遍化。 ( - 这是用于保持迁移兼容性的另一种语言"feature")
此时,我们应该忘记这个功能。不要试图泛化非泛型接口(除非你也可以重构子类型)。 尽可能避免使用原始类型。
您可能会引入新类型interface MyInt2<T> extends MyInt
,以便MyInt
的现有子类型不受影响。