Generics inheritance

P

Philipp

Hello
Why can't I call a method with signature
doSomething(Collection<Point> points)

with an argument ArrayList<MyPoint> (where MyPoint extends Point and
ArrayList implements Collection)?

How should I work around this?

Thank you for your answers
Philipp



Example code:

== Test.java ==
import java.awt.Point;
import java.util.ArrayList;
import java.util.Collection;

public class Test {
public static void main(String[] args) {
ArrayList<MyPoint> list = new ArrayList<MyPoint>();
list.add(new MyPoint(1,2,5));
doSomething(list); // gives compile error
}

public static void doSomething(Collection<Point> points){
for(Point p: points){
System.out.println(p);
}
}
}

== MyPoint.java ==
import java.awt.Point;

public class MyPoint extends Point {
public int height;
public MyPoint(int i, int j, int height) {
super(i,j);
this.height = height;
}
}
 
H

Hendrik Maryns

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Philipp schreef:
Hello
Why can't I call a method with signature
doSomething(Collection<Point> points)

with an argument ArrayList<MyPoint> (where MyPoint extends Point and
ArrayList implements Collection)?

even if B extends A. Thoroughly said:
How should I work around this?

Either you change the signature of the method to

void doSomething(Collection<? extends Point> points)

or, if you do not have access to its implementation, wrap your ArrayList
into another one:

List<Point> lessSpecificList = new ArrayList<Point>(myList);
doSomething(lessSpecificList)

But note that this can give problems, if stuff happens to the less
specific list. (In the case below, there is not problem.)

HTH, H.
Example code:

== Test.java ==
import java.awt.Point;
import java.util.ArrayList;
import java.util.Collection;

public class Test {
public static void main(String[] args) {
ArrayList<MyPoint> list = new ArrayList<MyPoint>();
list.add(new MyPoint(1,2,5));
doSomething(list); // gives compile error
}

public static void doSomething(Collection<Point> points){
for(Point p: points){
System.out.println(p);
}
}
}

== MyPoint.java ==
import java.awt.Point;

public class MyPoint extends Point {
public int height;
public MyPoint(int i, int j, int height) {
super(i,j);
this.height = height;
}
}


- --
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGZoroe+7xMGD3itQRAvRrAJ9TraWDw4PnL0EeWzThqd/4TT54rwCfToOl
vILY2FwgDXHlKHVDZP0VVBQ=
=sEJg
-----END PGP SIGNATURE-----
 
P

Philipp

Hendrik Maryns a écrit :
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Philipp schreef:


Either you change the signature of the method to

void doSomething(Collection<? extends Point> points)

Thanks, I'll do this (and also take your advice to "Thoroughly read a
generics tutorial" :) )

Philipp
 
L

Lew

Philipp schreef:
How should I work around [that Collection<A> does not extend Collection<B> even though A extends B?]

Hendrik Maryns a écrit :
Thanks, I'll do this (and also take your advice to "Thoroughly read a
generics tutorial" :) )

Sun's are pretty good, and cover the issue of why (A <: B) !-> (X<A> <: X<B>).

<http://java.sun.com/docs/books/tutorial/extra/generics/index.html>
which has a page on "Generics and Subtyping":
<http://java.sun.com/docs/books/tutorial/extra/generics/subtype.html>

<http://java.sun.com/docs/books/tutorial/java/generics/index.html>
which has pages on subtyping and wildcards also.

The "Really Big Index" of Sun tutorials is a gold mine:
<http://java.sun.com/docs/books/tutorial/reallybigindex.html>
 
S

Stefan Ram

Philipp said:
Why can't I call a method with signature
doSomething(Collection<Point> points)
with an argument ArrayList<MyPoint>
(where MyPoint extends Point and
ArrayList implements Collection)?

A Collection of Points can do more than a Collection of
MyPoints (i.e., accept a Point), therefore, a Collection of
MyPoints is not a subtype of it.

Assume,

java.util.List<java.lang.String> stringList =
new java.util.ArrayList<java.lang.String>();

Now assume, the following assignement would be allowed:

java.util.List<java.lang.Object> objectList = stringList;

Then one could add an object to this »objectList«:

objectList.add( new java.lang.Object(){} );

However, this would break the type of »stringList«, because
the following call to the get-Operation of the stringList now
will not return a string, because we have been allowed to add
an object above:

java.lang.String string = stringList.get( 0 );
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top