Java中的通用接口继承

时间:2019-04-19 07:33:00

标签: java inheritance

我已经使用以下方法在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方法。

能帮我理解吗?

4 个答案:

答案 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
  }  
}