Java 方法参数超类的接口实现

Java 方法参数超类的接口实现,java,interface,method-signature,Java,Interface,Method Signature,作为本主题中一般问题的一个实际示例,我想在与的Set接口中实现containsAll方法 public boolean containsAll(Iterable<?> c) { /* ... */ } 由于您正在实现的接口声明了(抽象)方法包含所有(集合),因此您必须使用这个确切的签名来实现它。Java不允许使用比原始方法更宽的参数类型来实现/重写方法。这就是为什么在使用集合签名注释方法时会出现错误 当该方法未被注释掉时,您不会显示您声称得到的另一个错误,但我想这可能与不明确的方法

作为本主题中一般问题的一个实际示例,我想在与的
Set
接口中实现
containsAll
方法

public boolean containsAll(Iterable<?> c) { /* ... */ }

由于您正在实现的接口声明了(抽象)方法
包含所有(集合)
,因此您必须使用这个确切的签名来实现它。Java不允许使用比原始方法更宽的参数类型来实现/重写方法。这就是为什么在使用
集合
签名注释方法时会出现错误


当该方法未被注释掉时,您不会显示您声称得到的另一个错误,但我想这可能与不明确的方法重载有关。

关于java为什么有此限制,我的猜测是,假设您有:

class A {
    void foo(String s) { ...  }
}

class B extends A {
    // Note generalized type
    @Override void foo(Object s) { ...  }
}
现在,如果您有
类C扩展了B
,并且它想要覆盖
foo
,那么不清楚它应该采用什么参数


例如,C首先直接扩展A,覆盖
void foo(String s)
,然后它被更改为扩展B。在这种情况下,C对
foo
的现有覆盖将变得无效,因为B的
foo
应该能够处理所有
对象,而不仅仅是
String
s

参数类型是方法签名的一部分,因此jvm需要具有完全相同签名的方法来查找覆盖。containsAll(Iterable)的签名与containsAll(Collection)的签名不同

如果我没记错的话,编译器必须使用一些变通方法来使泛型工作,尽管有这个限制


对于第二个问题,编译器更喜欢Collection参数,因为它是Iterable的子类型,这使得Collection方法比Iterable方法更具体

你能发布Eclipse给你的一个错误吗?在IDEA中对我有用。@Nikita:在中编辑。哦…这可能只是一个日食事件?这是一个术语噩梦。我逃避了这些挑战。看来,彼得的答案是正确的,当你们实现抽象方法时,你们必须遵循精确的签名。我可能设置的示例不准确,必须再次检查。我在NetBeans 6.8中遇到了相同的错误。如果没有注释掉该方法,则不会出现错误。只有当带有
集合
签名的一个是。另外,您是否了解为什么会出现这种情况?这是否符合@oksayt的回答?@Carl,你是说Java为什么设计成这样?可能是。啊,这似乎是一个合理的解释——扩展接口将要求子类维护扩展的接口。尽管如此,这似乎应该被允许——通常,子类不允许缩小接口。这也可能使虚拟表的设计更加清晰,可以断言其中的所有方法都具有确切的签名。或者他们只是想,如果他们对它进行了足够的详细说明,就可以让它发挥作用,但没有看到迫切的需求,就忽略了它。我遗漏了一些东西——这个例子应该有效吗?在@Override注释上,我得到“Method不从其超类重写Method”。
class A {
    void foo(String s) { ...  }
}

class B extends A {
    // Note generalized type
    @Override void foo(Object s) { ...  }
}