当返回类型是List时,不能覆盖来自超类的方法

时间:2014-12-18 11:31:54

标签: java inheritance

当我想要返回ArrayList C2时,这是不可能的,因为返回类型不兼容。

package a;
class C1 {
  private final ArrayList<C2> c2s = new ArrayList<C2>();

  protected ArrayList<C2> getC2() { return c2s; }
}

class C2 {}

package b;
class C1 extends a.C1 {
    private final ArrayList<C2> c2s = new ArrayList<C2>();

  @Override
  protected ArrayList<C2> getC2() { return c2s; } // won't work
}

class C2 extends a.C2 {}

更新:为什么这不起作用,以下作品(在.C1和b.C1中):

private final C2 c2 = new C2();

public C2 getC2() { return c2; }

1 个答案:

答案 0 :(得分:1)

您有两个不同的C2类 - ArrayList<a.C2>ArrayList<b.C2>不同。他们不相容避免这种事情:

ArrayList<b.C2> listB = new ArrayList<b.C2>();
ArrayList<a.C2> listA = listB; // This is invalid...
listA.add(new a.C2());
b.C2 firstElement = listB.get(0); // To stop this from causing problems.

这与覆盖无关,这只是普通的泛型。您可以将a.C1中的声明更改为:

protected ArrayList<? extends C2> getC2() { return c2s; }

然后它会起作用,因为类型是兼容的。这可以防止上述滥用行为,因为您无法在add上致电ArrayList<? extends a.C2>

顺便说一句,我会强烈阻止你拥有只能通过包来区分的类名。这是一个难以理解的代码和痛苦的调试会话的秘诀。它也是一个难以阅读的问题的配方,所以如果你的真实代码不使用这个令人讨厌的命名方案,请不要让你的示例代码使用它。