我已经使用以下方法在Java中创建了一个接口:
interface ReaderInterface{
public <k,v> Map<k,v> fetch(k id);
public <k,v> Map<k,v> fetchAll();
}
然后我创建了一个实现该接口的类:
class JSONreaderImpl implements ReaderInterface{
public Map<String, String> fetchAll(){
// This compiler is allowing to be override from interface \
}
public Map<String, String> fetch(String id){
// This is not being considered as an override method, compiler throwing an error to implement the fetch method
}
}
我的问题是,为什么在特定类上创建fetchAll方法时将其视为替代方法,为什么不使用fetchAll方法。
能帮我理解吗?
答案 0 :(得分:4)
您正在尝试使用这两种方法来获取相同类型的实体,不是吗? 在这种情况下,设计是错误的:您应该对整个接口进行参数化,而不是对每个方法分别进行参数化:
interface ReaderInterface<k, v> {
public Map<k, v> fetch(k id);
public Map<k, v> fetchAll();
}
class JSONreaderImpl implements ReaderInterface<String, String> {
public Map<String, String> fetchAll() { return null; }
public Map<String, String> fetch(String id) { return null; }
}
否则(分别设置每个方法的参数,您打算允许类似的实现
public Map<String, Boolean> fetchAll() { return null; }
public Map<Integer, List<Double>> fetch(Integer id) { return null; }
答案 1 :(得分:1)
要了解为什么fetch
不起作用,您可以查看下一个示例。
ReaderInterface foo = new JSONreaderImpl();
foo.<Integer, Integer>fetch(Integer.valueOf(1));
使用fetch
通用参数调用<Integer, Integer>
,但是实现期望它们是<String, String>
。为防止此编译器引发错误。
我不明白为什么fetchAll
起作用。可能是一些擦除魔术,它实际上引发了有关“未经检查的覆盖”的警告。
答案 2 :(得分:1)
@talex是正确的,尽管具有挑衅性的设计,但原始问题绝对值得回答。
Type erasure for generic methods
解释了无界类型参数已编译为Object
。
因此,声明此接口
interface Q {
public <K, V> Map<K, V> fetch(K id);
}
您确实需要在运行时扩展以下界面
interface Q {
public Map<Object, Object> fetch(Object id);
}
编译器特别注意方法参数,因为它们参与了正确的调用签名检测,它不允许您使声明的参数类型更具体并保持相同的签名。同时。 返回类型不会给我们带来太多麻烦。
因此您可以将以下实现检测为同一签名
abstract class QA implements Q {
public abstract Map<Integer, String> fetch(Object id);
}
但不能担任这个角色:
abstract class QA implements Q {
public abstract Map<Integer, String> fetch(Integer id);
}
如果您实际上想要某种特定于方法参数的参数,请以某种方式 bound 绑定您的类型参数-这样就可以使用更广泛的信息进行编译。
interface O {
<K extends List, V> V process(K id);
}
abstract class OA implements O {
public abstract String process(List id);
}
答案 3 :(得分:0)
问题还不是很清楚,但是如果这是您要实现的目标
interface Reader<T>.
{
Map fetchAll();
Map fetch(T id);
}
Impl
public class JSONReader implements Reader<String>
{
@Override
Map<String, String> fetch(String id)
{
// code
}
@Override
Map<String, String> fetchAll()
{
//code
}
}