【问题标题】:Java Generics: override method that differs in parameterized return typeJava泛型:参数化返回类型不同的覆盖方法
【发布时间】:2015-05-22 07:56:11
【问题描述】:

我来自 .Net,对 Java 开发还很陌生,所以也许这是一个奇怪的问题:

我有一个类层次结构,例如:

Superclass implements GenericInterface<Superclass>
    ^
    |
 Subclass

GenericInterface 非常简单:

public interface GenericInterface<T> {
    OtherGenericInterface<T> getOther();
}

OtherGenericInterface终于使用了类型参数:

public interface OtherGenericInterface<T> {
    List<Object> processType(T left, T right);
}

现在当我尝试在Superclass 中实现接口时,我只是返回一个匿名类型:

public class Superclass implements GenericInterface<Superclass> {
    @Override
    public OtherGenericInterface<Superclass> getOther() {
        return new OtherGenericInterface<Superclass>() {
            @Override
            public List<Object> processType(T left, T right) {
                ...
            }
        };
    }
}

到目前为止效果很好,但现在我尝试覆盖 Subclass 中的方法:

public class Subclass extends Superclass (implements GenericInterface<Subclass>) {
    @Override
    public OtherGenericInterface<Subclass> getOther() {
        ...
    }
}

在那里,我不能用我更具体的返回类型覆盖该方法。即使我重新实现接口并将超类中的方法声明为 final 也是不可能的。

所以我的问题是:为什么OtherInterface&lt;MoreSpecificType&gt; 不是更具体的类型,或者至少不是相同的类型(由于类型擦除),因为这将是重写方法的要求吗?。

【问题讨论】:

  • OtherInterface&lt;Subclass&gt; 不是OtherInterface&lt;Superclass&gt; 的子类型,原因相同ArrayList&lt;Integer&gt; 不是ArrayList&lt;Object&gt; 的子类型
  • 但它也不是同一类型?
  • 没有?当然OtherInterface&lt;Subclass&gt;OtherInterface&lt;Superclass&gt; 不是同一类型...

标签: java generics inheritance overriding


【解决方案1】:

这表明了对 Java 泛型的一个常见误解——认为匹配的类也会匹配子类(如参数类型)。事实并非如此。 Java 泛型旨在确保类型完全匹配。如果您想要灵活的空间,您必须指定并定义您想要的空间和数量。

这是一个允许您通过将签名准确指定为&lt;T extends Superclass&gt; 来做您想做的事情的版本。这可能不是您正在寻找的东西,但我希望它能为您指明正确的方向。

public interface OtherGenericInterface<T> {

    List<Object> processType(T left, T right);
}

public interface GenericInterface<T> {

    OtherGenericInterface<T> getOther();
}

public class Superclass<T extends Superclass> implements GenericInterface<T> {

    @Override
    public OtherGenericInterface<T> getOther() {
        return new OtherGenericInterface<T>() {
            @Override
            public List<Object> processType(Superclass left, Superclass right) {
                return null;
            }
        };
    }
}

public class Subclass extends Superclass {

    @Override
    public OtherGenericInterface<Subclass> getOther() {
        return null;
    }
}

【讨论】:

    猜你喜欢
    • 2020-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-18
    • 2018-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多