0

假设我有一个如下界面:

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

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

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

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

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

4

2 回答 2

2

如果Foo是一个接口:

一个类不能同时是两个接口类型的子类型,这两个接口类型是同一个通用接口的不同参数化 [...],否则会发生编译时错误。

所以不行。( JLS 8.1.5 )

无论如何,这实际上没有任何意义,因为您会贬低BardoSomething. 也许它是一个Double.

另一方面,您仍然可以这样做:

class Bar2 extends Bar {
    @Override
    public Integer doSomething() {...}
}

还是编译器不够聪明,无法检测到这种情况?

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

于 2014-11-24T06:45:46.637 回答
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> { ... }

这不会产生编译时错误,如果你doSomething()在 Bar2 中实现,它会在你这样做时考虑到这一点:-

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

否则它将运行doSomething()fromBar

显然,如果你这样做: -

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

它将考虑到doSomething()Bar因为这次它确实只考虑了一个实现doSomething(),即Bar(你必须实现它,因为Bar正在实现接口Foo:))

于 2014-11-24T06:41:22.910 回答