Car*_*arl 6 java interface method-signature
作为该主题中一般问题的一个实际例子,我想containsAll在Set界面中实现该方法
public boolean containsAll(Iterable<?> c) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
我想这应该是允许的,因为Collection是Iterable意味着这种containsAll将涵盖接口要求.同样,更普遍的是能够实现与参数超类的接口似乎应该工作.
然而,Eclipse说没办法(没有试过直接javac) - 有人可以解释原因吗?我确信规范中的某些内容使其成为现实,但我也想了解需求的动机.或者我错过了Iterable<?>不是超类的东西Collection<?>?
作为一个附带问题 - 鉴于我正在声明两个方法,带有Iterable签名的方法总是首选带有Collection参数的调用?
Eclipse错误:
如果我删除带Collection签名的方法,只留下Iterable一个(见错误后),我得到以下内容:
The type BitPowerSet must implement the inherited abstract method Set<Long>.containsAll(Collection<?>)
确切的实施是:
@Override public boolean containsAll(Collection<?> c) {
for (Object o : c) if (!contains(o)) return false;
return true;
}
public boolean containsAll(Iterable<?> c) {
for (Object o : c) if (!contains(o)) return false;
return true;
}
Run Code Online (Sandbox Code Playgroud)
由于您正在实现的接口声明了(抽象)方法containsAll(Collection<?>),因此必须使用此精确签名实现它.Java不允许您使用比原始参数类型更宽的参数类型来实现/覆盖方法.这就是您在使用Collection签名注释掉方法时出现的错误的原因.
当没有注释掉该方法时,您没有显示您声称获得的其他错误,但我想它可能需要对模糊方法重载执行某些操作.
我对为什么 java 有这个限制的猜测是,假设你有:
class A {
void foo(String s) { ... }
}
class B extends A {
// Note generalized type
@Override void foo(Object s) { ... }
}
Run Code Online (Sandbox Code Playgroud)
现在,如果你有class C extends B并且它想要覆盖foo,则不清楚它应该采用什么参数。
例如,C 首先直接扩展 A,覆盖void foo(String s),然后更改为扩展 B。在这种情况下,C 现有的覆盖foo将变得无效,因为 Bfoo应该能够处理所有Objects,而不仅仅是Strings。
| 归档时间: |
|
| 查看次数: |
905 次 |
| 最近记录: |