我正在尝试以这种方式覆盖通用类的方法:
public class MyGenFun<T extends CharSequence> extends Do<String>{
public void doX(T s){
System.out.println("in CHILD");
}
public static void main (String ...a){
MyGenFun<String> x = new MyGenFun<>();
x.doX("Test"); /// LINE 1
}
}
class Do<A>{
public void doX(A a){
System.out.println("in Super");
}
}
为什么我不能?编译错误是
yGenFun.java:15:错误:对doX的引用不明确,Do中的方法doX(A)和MyGenFun中的方法doX(T)匹配 x.doX( “测试”); ^ 其中A,T是类型变量: 在类Do中声明的extends Object T扩展了MyGenFun类中声明的CharSequence 1错误
如果我评论“第1行”,我可以编译代码。所以我认为我压倒一切。
答案 0 :(得分:4)
这是因为你不实际上覆盖了该方法,只是重载它。要覆盖,所有参数类型必须匹配。所以正确的覆盖方法是
public void doX(String s) {
}
T
是扩展CharSequence的东西,可能是String
但不一定是String
,例如它也可以是CharBuffer
。
您实例化以下内容:
MyGenFun<String> x = new MyGenFun<>();
因为你没有重写这个方法而是重载它,现在有两个方法在当前上下文中具有相同的签名,一个来自子类,一个来自超类:
public void doX(String a) {
...
}
答案 1 :(得分:3)
拥有此类层次结构,您有两个带签名的重载方法:
public void doX(String s){
}
public void doX(CharSequence s){
}
当您将String
传递给doX
时,编译器无法推断要调用的两种方法中的哪一种,因为String
与String
和{{1}兼容在同一时间。
所以,你应该像这样覆盖:
CharSequence
答案 2 :(得分:0)
你的方法签名说你需要一个参数传递, public void doX(T s);
public class MyGenFun<T extends CharSequence> extends Do<T>{
@Override
public void doX(T s){
System.out.println("in CHILD");
}
}