我有Java类:
abstract class Parent {
abstract void test(Object pObject, Map<String, Object> pData);
}
public class Test extends Parent {
@Override
void test(Object pObject, Map<String, Object> pData) {
}
}
并希望将代码重构为:
abstract class Parent<T> {
abstract void test(T pObject, Map<String, Object> pData);
}
public class Test extends Parent {
@Override
void test(Object pObject, Map<String, Object> pData) {
}
}
Eclipse(4.4.2如果它的问题)告诉我Test类中的代码无效(编译时错误)并且正确的test()
方法签名必须是:
@Override
void test(Object pObject, Map pData) {
}
我的问题是为什么!?
实际上,真实的故事有点长。我有很多孩子上课(比如测试)并且不想改变它们,而更喜欢使用泛型(即<T>
类)来为父类的新孩子。在这两种情况下,test()
方法的第二个参数必须为Map<String, Object>
。
有什么想法吗?
答案 0 :(得分:5)
我的问题是为什么!?
当您扩展{strong>原始版本的Parent
时,该类中的所有通用信息都会被忽略。因此,您正在扩展Parent
,如下所示:
abstract class Parent {
abstract void test(Object pObject, Map pData);
}
为了保留 Map
参数的类型参数,您只需指定您正在扩展Parent<Object>
。现在这段代码编译得很好:
public class Test extends Parent<Object> {
@Override
void test(Object pObject, Map<String, Object> pData) {
}
}
答案 1 :(得分:3)
在第一个例子中,Parent
是一个普通的类,你以预期的方式对它进行了分类,一切都很好。
在第二个示例中,您没有扩展Parent<T>
,而是扩展了通用的已擦除Parent
,即使它们不涉及T
,也会删除该类中的所有泛型。< / p>
试
public class Test extends Parent<Object> {
@Override
void test(Object pObject, Map<String, Object> pData) {
}
}
答案 2 :(得分:2)
我看到达到你想要的唯一方法是保持Parent
类不变,并引入另一个类,为你提供模板功能:
abstract class TemplatedParent<T> {
abstract void test(T pObject, Map<String, Object> pData);
}
abstract class Parent extends TemplatedParent<Object> {}
这样您就可以保留旧代码,而需要模板功能的新代码必须直接扩展TemplatedParent
。