Reputation: 2036
When I want to return a ArrayList
of C2
, it's not possible, because the return types are incompatible.
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 {}
Update: Why doesn't this work, when following works (in a.C1 and b.C1):
private final C2 c2 = new C2();
public C2 getC2() { return c2; }
Upvotes: 0
Views: 88
Reputation: 1500785
You've got two different C2
classes - an ArrayList<a.C2>
isn't the same as an ArrayList<b.C2>
. They're incompatible to avoid this sort of thing:
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.
That has nothing to do with overriding, it's just normal generics. You could change your declaration in a.C1
to:
protected ArrayList<? extends C2> getC2() { return c2s; }
Then it would work, because the types will be compatible. That prevents the above abuse because you can't call add
on an ArrayList<? extends a.C2>
.
As an aside, I would strongly discourage you from having class names which are only distinguished by package. It's a recipe for unreadable code and painful debugging sessions. It's also a recipe for hard-to-read questions, so if your real code doesn't use this nasty naming scheme, please don't make your sample code use it either.
Upvotes: 1