假设我有如下界面:
public interface Foo<T> {
T doSomething();
}
现在,是否允许以下两种情况?
public class Bar implements Foo<Number> { ... }
public class Bar2 extends Bar implements Foo<Integer> { ... }
一方面,我似乎不这么认为,因为Bar2
“实现Foo
两次”,即使Integer
是Number
的子类。另一方面,这不是doSomething()
上的协变返回类型的情况吗?或者编译器不够聪明,无法进行检测?
答案 0 :(得分:2)
如果Foo
是一个界面:
一个类可能不会同时是两个接口类型的子类型,这两个接口类型是同一个通用接口的不同参数化,或者发生编译时错误。
所以没有。 (JLS 8.1.5)
无论如何它都没有意义,因为你会倾向于Bar
从doSomething
返回的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
:))