【问题标题】:Cannot implement Interface with different type arguments无法实现具有不同类型参数的接口
【发布时间】:2017-05-10 15:39:16
【问题描述】:

我有一个通用接口A<T>,我有一个实现A<String> 的B 类。我创建了一个类C,它扩展了B 并实现了A<Number>。 对于 C ,我收到编译错误消息:

A cannot be inherited with different type arguments <String> and <Number>.

为什么不允许这样做? 如果这个问题的答案是类型擦除,那么请详细解释一下。

示例代码:

public interface A<T> {

}

public class B implements A<String> {

}

public class C extends B implements A<Number> {
}

【问题讨论】:

  • 如果您提供了一个可以使用的代码框架,回答这个问题会稍微容易一些。没什么大不了的,但足以重现您面临的相同错误。
  • @Raj 在问题中请
  • 怎么可能?想想看。 C 已经通过 B 实现了 A
  • C 已经通过 B 实现了 A ,但它没有实现 A
  • C 已经通过 B 实现了 A ,但它没有实现 A 。如果你只是创建一个非泛型类和非泛型接口 A, B,C ;你可以这样做 B 实现 A 和 C 扩展 B 实现 A——这对于非泛型是完全有效的。

标签: java generics inheritance interface subclass


【解决方案1】:

第 8.1.5 节中的 Java 语言规范声明如下:

一个类不能同时是两个接口类型的子类型 它们是同一个通用接口的不同参数化 (§9.1.2),或泛型接口参数化的子类型 以及命名相同通用接口的原始类型,或编译时 发生错误。

引入此要求是为了支持 按类型擦除翻译(第 4.6 节)。

这意味着在擦除后,您的类最终会得到具有相同签名的方法(如果有的话)。详情请参考 Angelika Langer 的site

【讨论】:

    【解决方案2】:

    老实说,如果你能做到,那就没有意义了。

    这是场景:

    • B 实现 A 并将 A&lt;T&gt; 绑定到 A&lt;String&gt;
    • C 继承自 B已经绑定到 A&lt;String&gt;),并且您正在尝试实现 A&lt;Number&gt;

    你不能同时实现一个类型。

    如果您想以某种方式将Number 合并到C 中,那么您必须将类型on C 而不仅仅是A

    这会编译,但看起来很奇怪:

    public class C<T> extends B implements A<String> {
    
    }
    

    归根结底,这真的归结为您的层次结构需要如何布局。如果您真的需要BC 之间的关系,那么以这种方式具体化它们的类型是没有意义的;只是让他们使用T 作为泛型。最后,通过继承,你仍然可以访问C中的AB的通用合约,所以你不需要实现它。

    public interface A<T> {
    
    
    }
    
    public class B<T> implements A<T> {
    
    }
    
    public class C<T> extends B<T> {
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-27
      相关资源
      最近更新 更多