This week's book giveaway is in the Servlets forum.
We're giving away four copies of Murach's Java Servlets and JSP and have Joel Murach on-line!
See this thread for details.
The moose likes Beginning Java and the fly likes ArrayList Polymorphism Question Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "ArrayList Polymorphism Question" Watch "ArrayList Polymorphism Question" New topic
Author

ArrayList Polymorphism Question

Hunter McMillen
Ranch Hand

Joined: Mar 13, 2009
Posts: 492

I have four Node type classes: Node, InputNode, HiddenNode, and OutputNode. InputNode, HiddenNode, and OutputNode all extend the Node class.

Now I have another class called Layer, inside Layer I need an ArrayList of type Node to keep track of what Node objects belong to which Layer object.
I am trying to do this:



I am unsure why this error occurs since InputNode, HiddenNode, and OutputNode all extend from Node. I thought I was able use the superclass to declare an object, and a subclass to define an object.

Any help would be great,
Thanks
Hunter


"If the facts don't fit the theory, get new facts" --Albert Einstein
Ralph Cook
Ranch Hand

Joined: May 29, 2005
Posts: 479
You need to read a little more about generics. This is one of the first major hurdles you run into using them.

Yes, Node is a superclass of HiddenNode.

ArrayList<Node> is NOT a superclass of ArrayList<HiddenNode>.

I know it makes sense that it is, but it is not. The fact that it is not was easier for me to understand after I learned that all this lovely type-checking information we write all those angle-brackets for is NOT available at runtime -- Java checks these things at compile time, and boils them all down to their most generic form at runtime.

Therefore, as far as the runtime is concerned, you can put any subclass of Node into ArrayList<Node>, and that makes it unsuitable for holding any specific subclass of node.

You can read about having an ArrayList<? extends Node>, which may be the closest thing to what you want. It will not, however, check that only one subclass of node is going into the list declared that way. If you really want to do that, you're going to have to declare one ArrayList for each subtype.

rc
Hunter McMillen
Ranch Hand

Joined: Mar 13, 2009
Posts: 492

Thanks for your response Ralph, that helped out a lot.
Do you think it would be a better design to just hold an ArrayList of each type of Node in its matching Layer. (i.e. InputLayer has an ArrayList of InputNodes, HiddenLayer has an ArrayList of HiddenNodes, etc. Rather than holding a singular list of type Node at in the Layer class, and trying to sort the issue out with generics.


Thanks
Hunter
Ralph Cook
Ranch Hand

Joined: May 29, 2005
Posts: 479
Well, I think it ought to partially depend on the operations you do with them. If all the operations you are liable to perform on HiddenLayer are specific to Hidden nodes, then that makes sense. On the other hand, if many of the operations in Layer are common to Node, so that there will be significant code that could operate on a generic node without having to know which kind of subclass of Node it is, then an ArrayList of <? extends Node> would allow Layer code to operate on "subclass of Node" without having to either duplicate the code or jury-rig the Layer methods to pass their specific subclass into a method that dealt with the superclass, etc. It really comes down to what kind of collection you are trying to represent; if you're going to have 3 different lists, then is Node and its subclasses really an inheritance relationship?

Anyway. Glad it helped.

rc
Hunter McMillen
Ranch Hand

Joined: Mar 13, 2009
Posts: 492

Well it's hard to say, I am constructing an artificial neural network, so some operations in Layer need to be able to apply to all Node type objects, but some operations are unique to the individual node classes and need to be accessed. If I am only storing an ArrayList<Node> in the super class, it makes it difficult to perform the individual operations, but If I have three ArrayList objects then I will be repeating similar code in lots of places. It's a kind of trade off I suppose, anyway thank you for you input, it has helped a lot.


Hunter
Ralph Cook
Ranch Hand

Joined: May 29, 2005
Posts: 479
Keep in mind that if the operations are (or can be) performed by the objects in the list, with parameters passed in from the Layer class, then the methods that do those operations can be defined on the specific Node subclasses and they can be stored in an ArrayList<? extends Node>. Unfortunately I don't know anything about neural networks, but let's say you have some kind of visible component for each node, and under some conditions the layer is going to tell specific elements to blink to get a viewer's attention. Let's say further that the blinking behavior is different for each kind of node. blink() can be defined as an abstract method on Node, overridden on each subclass, and called by Layer without any knowledge of which kind of node is being called.

I suppose another way of putting the question is whether the node collections are each different kinds of objects. Is each kind of object only in one layer? Is it the layers that are different kinds of object?

All of those are domain-specific questions -- the software may or may not be robust under any possibly organization; the question is what is it you're trying to represent and what is the most "natural" way to represent that in software given the tools that you have (in this discussion, OO design).

Good luck with it.

rc
 
 
subject: ArrayList Polymorphism Question
 
Similar Threads
Incompatible Types
Generics exercise in Head First Java 2nd ed.
override the equals and hashcode
print a HashSet of objects
Generics <? extends String> Question