如何更改子类中字段的通用类型?

时间:2019-02-08 16:30:54

标签: java generics inheritance

我有一个课程,A

import java.util.ArrayList;
import java.util.List;

public class A {

    protected List<Object> objects;

    public A() {
        objects = new ArrayList<Object>();
    }

    public A(List<Object> objects) {
        this.objects = objects;
    }

    public List<Object> getObjects() {
        return objects;
    }

    public void addObject(Object o) {
        getObjects().add(o);
    }

}

我想使用名为B的类对其进行子类化,但是将objects字段更改为List<Number>

import java.util.List;

public class B extends A {

    @Override
    public List<Number> getObjects() {
        return (List<Number>) super.getObjects();
    }

    @Override
    public void addObject(Object o) {
        getObjects().add((Number) o);
    }
}

但是,这将引发编译器错误。如何正确执行此操作?

2 个答案:

答案 0 :(得分:3)

为您的A类引入类型参数...

public class B extends A<Number> {

}

现在B实际上不需要重写方法...

accuracy

答案 1 :(得分:0)

这是泛型如何在Java中工作的关键细节。如果类型T扩展了类型U,我们期望List<T>扩展List<U>。但是事实并非如此。因此,当您尝试将List<Number>作为List<Object>的子类型返回时,编译器会抱怨。

请注意-抱怨与您在功能体内进行的转换无关,这本身就是危险的。它是关于函数的返回类型,该函数声称是重写。用花哨的话来说,返回类型与超类https://www.tutorialspoint.com/Covariant-return-types-in-Java中的方法不是“协变”的。

所以这解释了编译器错误背后的“原因”。

关于“如何”正确执行此操作。在没有看到用例的情况下,我必须说Bret C's Answer是我要做的方式。