Computer Science Canada

Determine instance

Author:  efus [ Wed Jan 07, 2009 6:06 am ]
Post subject:  Determine instance

I am trying to learn some oop in java. What I am trying to do is building a binary tree to convert an ekspresion in reverse police notation to infix notation. The problem is that I have three classes, one abstract called ArithmeticNode which represents a general node, a class called ValueNode representing a leaf with no children and the last class called OperatorNode representing a node with two children.

ArithmeticNode
code:

abstract class ArithmeticNode
{       
        protected Object data;
        protected String infixNotation;
       
        abstract Object printNode();
        abstract String infix();
}


ValueNode
code:


class ValueNode extends ArithmeticNode
{
       
        public ValueNode(Number value)
        {
                        super.data = value;
        }
       
        public Object printNode()
        {
                        return super.data;
        }
       
        public String infix()
        {
                super.infixNotation += super.data;
               
                return super.infixNotation;
        }
       
}




OperatorNode
code:

class OperatorNode extends ArithmeticNode
{

        Object leftChild;
    Object rightChild;
       
        public OperatorNode(Object operator, Object LC, Object RC)
        {
                this.leftChild = LC;
                this.rightChild = RC;
                super.data = operator;
        }
       
        public String printNode()
        {
                String node = new String();
               
                node = leftChild.toString();
                node += super.data.toString();
                node += rightChild.toString();
               
                return node;
        }
       
        public String infix()
        {
                super.infixNotation += leftChild.infix();
                super.infixNotation += super.data;
                super.infixNotation += rightChild.infix();
               
               
                return super.infixNotation;
        }
               

}




The problem I am having right now, is how do I know what the children in OperatorNode is an instance of. They can be both an OperatorNode or a ValueNode. Right now I have them as Object which does not work.
So the question is: is there a way to decide what instance each child is or do I need to restructure?

Author:  Nick [ Wed Jan 07, 2009 6:14 am ]
Post subject:  RE:Determine instance

couldn't you overload the method?

code:

public OperatorNode(Object operator, OperatorNode LC, OperatorNode RC)
{
      this.leftChild = LC;
      this.rightChild = RC;
      super.data = operator;
}
public OperatorNode(Object operator, ValueNode LC, ValueNode RC)
{
      this.leftChild = LC;
      this.rightChild = RC;
      super.data = operator;
}


that way it doesn't matter which you add Razz

Author:  efus [ Wed Jan 07, 2009 6:29 am ]
Post subject:  Re: Determine instance

well the children can be both an OperatorNode or a ValueNode. So one child could be a OperatorNode an the other a ValueNode. So I would have to have 4 constructors with identical code. This could probably work, but what do I do with the declaration of the children, right now they are declared as Objects.

Author:  DemonWasp [ Wed Jan 07, 2009 11:18 am ]
Post subject:  RE:Determine instance

Properly, your methods should always take the most general type of object they could reasonably apply to. This means that they shouldn't be OperatorNode OR ValueNode; they should also NOT be Object (which really shouldn't see a whole lot of use, ever).

What you should be using is ArithmeticNode. That means that each child can be either another OperatorNode or a ValueNode. Similarly, RC and LC should be declared as ArithmeticNode.

This neatly sidesteps having to write more than one version of the function (it may not save you much in this case, but if you had 3 different kinds of node, and up to 3 per function, you can probably see you'd rather not write the 27 methods for that).

The only "trick" to this method choosing the correct class. You want to choose one that's general enough to cover every case (if possible), and you want to choose one that isn't so general that it includes cases that are invalid (so Object would be a bad choice, since it allows me to pass a String or a BufferedReader or whatever else I want, even though those have no place in your tree). Using ArithmeticNode guarantees that everything in the tree is valid, while also allowing ANYTHING that's valid.

Plus, if math suddenly changes and allows a Whatsit type of node, you don't have to change much of anything that already exists, you just add Whatsit extends ArithmeticNode and go on your merry way.

Author:  SJ [ Thu Jan 08, 2009 11:34 pm ]
Post subject:  Re: Determine instance

referring to this specifically,

efus @ Wed Jan 07, 2009 6:06 am wrote:
The problem I am having right now, is how do I know what the children in OperatorNode is an instance of.


isn't that what the instanceof operator is for?

ie.
String s = "abc";
if (s instanceof String) // true!
doSomething();

Author:  DemonWasp [ Fri Jan 09, 2009 9:40 am ]
Post subject:  RE:Determine instance

Yes, you could use instanceof. However, that's generally something you can avoid if you design it properly. The simple modifications I suggested above will fix the problem with a minimum of effort, and are the most extensible.

What happens if you use instanceof and you later discover that you need a third, fourth, thirtieth class? You get to write out a LOT of long if statements! If you use my method, you don't have to change a thing.


: