代码之家  ›  专栏  ›  技术社区  ›  Carl

具有方法参数超类的接口实现

  •  6
  • Carl  · 技术社区  · 14 年前

    作为这个主题中一般问题的一个实际例子,我想实现 containsAll Set

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

    我想这应该是允许的,因为 Collection Iterable 意思是 集装箱

    然而,Eclipse说不行(没有直接尝试javac)-有人能解释一下原因吗?我确信在规范中有一些东西使它成为现在的样子,但是我也希望理解需求的动机。或者我错过了什么 Iterable<?> 不是一个超类 Collection<?> ?

    作为一个附带问题-假设我声明两个方法 如果电话中有 争论?

    Eclipse错误:

    收藏 签名,只留下 一(见错误之后),我得到以下信息:

    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;
    }
    
    3 回复  |  直到 14 年前
        1
  •  2
  •   oksayt    14 年前

    我对java为什么有这种限制的猜测是,假设您有:

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

    如果你有 class C extends B 它想超越 foo ,尚不清楚应该采取什么样的论据。

    例如,C首先直接扩展A,覆盖 void foo(String s) ,然后将其更改为扩展B。在本例中,C的现有重写 会变得无效因为 Object s、 不仅仅是 String s。

        2
  •  5
  •   Péter Török    14 年前

    containsAll(Collection<?>) ,必须使用此确切签名来实现它。Java不允许您实现/重写参数类型比原始类型更宽的方法。这就是为什么当您使用 Collection 签名。

        3
  •  0
  •   josefx    14 年前

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

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