键入继承问题

时间:2017-12-06 05:16:39

标签: java inheritance java-7

我真的不知道如何解释我的问题。下面是我所拥有的几个对象的示例。

假设我有课程

public class Foo{}
public class FooBar extends Foo{}

所有这一切都很好,但是如果我拿一个列表说我希望它充满Foo个对象,我就不能提供FooBar个对象。这是为什么?

示例:

List<Foo> fooList = Arrays.asList(new FooBar());

如果FooBar extends Foo,为什么不能将其转回Foo

2 个答案:

答案 0 :(得分:6)

正如评论Arrays.asList(T...)中已经提到的那样,返回List<T>。由于您将FooBar实例从Java 7传递给该方法类型推断,因此使用FooBar类型作为T表示,这意味着此方法返回List<FooBar>,无法将其分配给{ {1}}(您可以在Is List<Dog> a subclass of List<Animal>? Why aren't Java's generics implicitly polymorphic?

了解更多信息

在Java 8中,改进了类型推断,使lambdas更有用。现在List<Foo>不仅从参数中推断出类型,而且还从目标 - 引用变量中推断出应该保存结果的类型。这允许TT推断Foo而不是List<Foo> fooList参数。

要在Java 7等早期版本中解决此问题,您可以显式为泛型方法new FooBar()设置泛型类型

asList

更多信息:https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html(特别是“目标类型”部分)

答案 1 :(得分:3)

Arrays.asList(new FooBar())返回List<FooBar>,无法将其分配给List<Foo>。如果可以将其分配给它,则可以创建List<FooBar>,将其分配给List<Foo>,然后将Foo添加到必须包含FooBar的列表中,显然是一个错误。

相反,你需要:

List<Foo> fooList = new ArrayList<>();
fooList.add(new FooBar());