Genercis advice  
Author Message
Nomak





PostPosted: 2005-3-7 3:56:00 Top

java-programmer, Genercis advice Hello!

i've just read some docs about generics in Java, and i would like to do
a complete Canvas class. Here is my attempt:

import java.util.LinkedList;
import java.util.List;

public class Canvas {
private List<Shape> shapeList = null;

class Shape {
public void draw() {
}
}

class SubShape extends Shape {
public void draw() {
}
}

public Canvas() {
shapeList = new LinkedList<Shape>();

add(new SubShape());
drawAll();
}

public void drawAll() {
// TEH UGLYNESS !!!
List<? extends Shape> shapeList = this.shapeList;

for (Shape s:shapeList)
s.draw();
}

public void add(Shape s) {
shapeList.add(s);
}
}

From what i've understood:
- unbounded is for writing
- bounded is for reading

So basically, i have to use temporaries or i have to do a
"drawAll(bounded version)" wich is even worse.

I really hope i've missed something because i think this stink.

Any advice/explaination apreciated :)
 
Chris Smith





PostPosted: 2005-3-7 13:20:00 Top

java-programmer >> Genercis advice Nomak <email***@***.com> wrote:
> public class Canvas {
> private List<Shape> shapeList = null;
>

...

> public void drawAll() {
> // TEH UGLYNESS !!!
> List<? extends Shape> shapeList = this.shapeList;
>
> for (Shape s:shapeList)
> s.draw();
> }

That is allowed, but unnecessary. You could just as easily use a
reference to List<Shape> there, instead of List<? extends Shape>. The
difference is that a variable of type List<? extends Shape> can point to
an object of class List<Rectangle> (for example). Since the field
shapeList is of type List<Shape> and you don't assign anything else to
the local variable, that extra flexibility doesn't actually accomplish
anything here. However it doesn't hurt anything either, since a mere
List<? extends Shape> is enough knowledge to perform all operations that
you intend to perform.

> So basically, i have to use temporaries or i have to do a
> "drawAll(bounded version)" wich is even worse.

No, you don't have to do any of that. You must have seen an example
explaining what you *can* do, and misinterpreted it as something that
you *must* do.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
Mr Smith





PostPosted: 2005-3-7 16:49:00 Top

java-programmer >> Genercis advice On Sun, 6 Mar 2005 22:19:37 -0700
Chris Smith <email***@***.com> wrote:

> Nomak <email***@***.com> wrote:
> > public class Canvas {
> > private List<Shape> shapeList = null;
> >
>
> ...
>
> > public void drawAll() {
> > // TEH UGLYNESS !!!
> > List<? extends Shape> shapeList = this.shapeList;
> >
> > for (Shape s:shapeList)
> > s.draw();
> > }
>
> That is allowed, but unnecessary. You could just as easily use a
> reference to List<Shape> there, instead of List<? extends Shape>. The
> difference is that a variable of type List<? extends Shape> can point to
> an object of class List<Rectangle> (for example). Since the field
> shapeList is of type List<Shape> and you don't assign anything else to
> the local variable, that extra flexibility doesn't actually accomplish

you must have misread the constructor: there is a SubShape added to the list
 
 
megagurka





PostPosted: 2005-3-7 17:42:00 Top

java-programmer >> Genercis advice Nomak <email***@***.com> wrote in message news:<422b61a5$0$838$email***@***.com>...
> Hello!
>
> i've just read some docs about generics in Java, and i would like to do
> a complete Canvas class. Here is my attempt:
>
> import java.util.LinkedList;
> import java.util.List;
>
> public class Canvas {
> private List<Shape> shapeList = null;
>
> class Shape {
> public void draw() {
> }
> }
>
> class SubShape extends Shape {
> public void draw() {
> }
> }
>
> public Canvas() {
> shapeList = new LinkedList<Shape>();
>
> add(new SubShape());
> drawAll();
> }
>
> public void drawAll() {
> // TEH UGLYNESS !!!
> List<? extends Shape> shapeList = this.shapeList;
>
> for (Shape s:shapeList)
> s.draw();
> }
>
> public void add(Shape s) {
> shapeList.add(s);
> }
> }
>
> From what i've understood:
> - unbounded is for writing
> - bounded is for reading
>
> So basically, i have to use temporaries or i have to do a
> "drawAll(bounded version)" wich is even worse.
>
> I really hope i've missed something because i think this stink.
>
> Any advice/explaination apreciated :)

What are you trying to achieve? What's the point of the local variable
in drawAll()? Why not loop over the shapeList field?

/Jesper Nordenberg
 
 
Mr Smith





PostPosted: 2005-3-7 20:09:00 Top

java-programmer >> Genercis advice On 7 Mar 2005 01:41:50 -0800
email***@***.com (Jesper Nordenberg) wrote:

> What are you trying to achieve? What's the point of the local variable
> in drawAll()? Why not loop over the shapeList field?

You made me doubtful, so i try to compile a modified version of the code:

import java.util.LinkedList;
import java.util.List;

public class Canvas {
private List<Shape> shapeList = null;

class Shape {
public void draw() {
System.out.println("Shape.draw()");
}
}

class Circle extends Shape {
public void draw() {
System.out.println("Circle.draw()");
}
}

class Rectangle extends Shape {
public void draw() {
System.out.println("Rectangle.draw()");
}
}

public Canvas() {
shapeList = new LinkedList<Shape>();

add(new Circle());
add(new Rectangle());
drawAll();
}

public void drawAll() {
for (Shape s:shapeList)
s.draw();
}

public void add(Shape s) {
shapeList.add(s);
}

// Entry point
public static void main(String[] args) {
Canvas c = new Canvas();
}
}

The output:

$ java -version
java version "1.5.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_01-b08)
Java HotSpot(TM) Client VM (build 1.5.0_01-b08, mixed mode, sharing)
$ javac Canvas.java
$ java Canvas
Circle.draw()
Rectangle.draw()
$

So it works great... but from this document:

http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf


It is said that for dynamic dispatch on Shape.draw() in drawAll(), the collection must be on "? extends Shape". So my code shouldn't work... i don't understand :(

Was the generics modified in "update 1" of JSE 5.0 ?
 
 
Chris Smith





PostPosted: 2005-3-7 22:19:00 Top

java-programmer >> Genercis advice Mr Smith <email***@***.com> wrote:
> you must have misread the constructor: there is a SubShape added to the list
>

No, I did not misread the constructor. Despite there being a SubShape
added to the list, the list itself has a class of List<Shape>. The
single most important thing to get straight in generic collections is
that the class of a collection does *not* depend on what's in it. I can
have a List<Object> that contains only JComponent instances... but it's
still NOT a List<JComponent> if I created it by writing something like
"lst = new List<Object>()".

In your case, the field shapeList points to an object of the collection
class List<Shape>, and NOT List<SubShape>. Because SubShape is
assignable to Shape, it's possible to add a SubShape to shapeList, but
that doesn't change the class of the object.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
 
Lasse Reichstein Nielsen





PostPosted: 2005-3-8 6:32:00 Top

java-programmer >> Genercis advice Mr Smith <email***@***.com> writes:

> So it works great... but from this document:
>
> http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
>
>
> It is said that for dynamic dispatch on Shape.draw() in drawAll(), the collection must be on "? extends Shape". So my code shouldn't work... i don't understand :(

Without checking the tutorial, I guess it's because the Canvas in there is
parameterized by the List of shapes.

You have fixed on a List<Shape>, so you can use that you know that.

They have the list provided to them, and all all they require is that
it is a list of shapes, which any list matching "List<? extends Shape>"
satisfies.

> Was the generics modified in "update 1" of JSE 5.0 ?

No.

/L
--
Lasse Reichstein Nielsen - email***@***.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
 
 
megagurka





PostPosted: 2005-3-8 16:58:00 Top

java-programmer >> Genercis advice Mr Smith <email***@***.com> wrote in message news:<20050307130915.34831643@recif>...
> So it works great... but from this document:
>
> http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
>
>
> It is said that for dynamic dispatch on Shape.draw() in drawAll(), the collection must be on "? extends Shape". So my code shouldn't work... i don't understand :(

No, it doesn't say that. It's a common misconception people have with
generics. List<Shape> means a list which contains instances of Shape
or any sub class of Shape, so you can call any method in Shape on the
objects in the list. List<? extends Shape> means a list of Shapes or a
sub class of Shape. So, both List<Shape> and List<SubShape> fits this
wildcard. The difference between List<Shape> and List<? extends Shape>
is when you call methods on the List. For example, you can't add a
Shape to a List<? extends Shape> because it might not be a list of
Shapes.

/Jesper Nordenberg
 
 
Mr Smith





PostPosted: 2005-3-8 20:42:00 Top

java-programmer >> Genercis advice On 8 Mar 2005 00:57:46 -0800
email***@***.com (Jesper Nordenberg) wrote:

> > http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

> No, it doesn't say that. It's a common misconception people have with
> generics. List<Shape> means a list which contains instances of Shape
> or any sub class of Shape, so you can call any method in Shape on the
> objects in the list. List<? extends Shape> means a list of Shapes or a
> sub class of Shape. So, both List<Shape> and List<SubShape> fits this
> wildcard. The difference between List<Shape> and List<? extends Shape>
> is when you call methods on the List. For example, you can't add a
> Shape to a List<? extends Shape> because it might not be a list of
> Shapes.

thx a lot !!!

i've read again the page 6 of the pdf, and with your explaination standing next to the pdf, i understood it right :)