接口,泛型和协变返回类型

时间:2014-11-24 06:25:28

标签: java generics interface covariant

假设我有如下界面:

public interface Foo<T> {
    T doSomething();
}

现在,是否允许以下​​两种情况?

public class Bar implements Foo<Number> { ... }

public class Bar2 extends Bar implements Foo<Integer> { ... }

一方面,我似乎不这么认为,因为Bar2“实现Foo两次”,即使IntegerNumber的子类。另一方面,这不是doSomething()上的协变返回类型的情况吗?或者编译器不够聪明,无法进行检测?

2 个答案:

答案 0 :(得分:2)

如果Foo是一个界面:

  

一个类可能不会同时是两个接口类型的子类型,这两个接口类型是同一个通用接口的不同参数化,或者发生编译时错误。

所以没有。 (JLS 8.1.5

无论如何它都没有意义,因为你会倾向于BardoSomething返回的Double。也许这是一个class Bar2 extends Bar { @Override public Integer doSomething() {...} }

另一方面,你可能仍然这样做:

{{1}}
  

或者编译器不够聪明,无法进行检测吗?

我们和编译器认为在这里并不重要。编译器绑定到指示错误的语言规范。

答案 1 :(得分:0)

这不是一个接口,它似乎是一个类(或者是一个也缺少关键字abstract的抽象类),它应该是这样的: -

public interface Foo<T> {
        T doSomething();
}

除此之外

public class Bar implements Foo<Number> { ... }

public class Bar2 extends Bar implements Foo<Integer> { ... }

会给你编译时错误, The interface Foo cannot be implemented more than once with different arguments: Foo<Number> and Foo<Integer>

但如果您改为: -

public class Bar implements Foo<Integer> { ... }

public class Bar2 extends Bar implements Foo<Integer> { ... }

这不会产生编译时错误,如果您在Bar2中实现doSomething(),则在执行此操作时会考虑到这一点: -

Bar2 bar2=new Bar2();
bar2.doSomething();

或者它会从doSomething()

运行Bar

显然如果你这样做: -

Bar bar=new Bar();
bar.doSomething();

它会考虑doSomething()的{​​{1}},因为这次只考虑了一个Bar,即doSomething()(你必须实施)因为Bar正在实现接口Bar :))

相关问题