Search code examples
javaprocessing

Java workaround for instanceof


I am making a GUI with function blocks in Java/Processing.

I have a general class which has methods just to manage the X and Y coordinates. All the blocks themselfs inherrit from the general class.

This allow me to make a single array list

ArrayList <FunctionBlock> blocks = new ArrayList() ;

I can add and remove function blocks at will.

The problem I am having is that I have to use instanceof. For instance.

    for (int i = 0; i < blocks.size(); i++)          // loop through all blocks
    {
        FunctionBlock block = blocks.get(i) ;        // declare a local function block

        if(block instanceof AND)    {    AND    and =   (AND) block ;   and.draw() ; }  // Can I do it differently?
        if(block instanceof OR)     {     OR     or =    (OR) block ;    or.draw() ; }
        if(block instanceof SR)     {     SR     sr =    (SR) block ;    sr.draw() ; }
        if(block instanceof DELAY)  {  DELAY  delay = (DELAY) block ; delay.draw() ; }
        if(block instanceof NOT)    {    NOT    not =   (NOT) block ;   not.draw() ; }
    }

Each individual function block has a draw() method. For every new block I add, I need to update this list among others.

I would prefer to use something like this

   for (int i = 0; i < blocks.size(); i++)          // loop through all blocks
    {
        FunctionBlock block = blocks.get(i) ;        // declare a local function block

         block.draw() ;    // compiler error ==> The function draw() does not exist. 

In a single for-loop I want to call the draw() methods of all sub classes without having to check what the object is.

Is this possible and if so, how?


Solution

  • The error is happening because the FunctionBlock has no method called draw(). Add this method to your class FunctionBlock class:

    public abstract class FunctionBlock {
        /** Draws the block */
        public abstract void draw();
        ...
    

    Then in your subclasses, add the @Override annotation to the implementations:

    @Override
    public void draw() {
        ...
    }
    

    Alternatively, you could define an interface that contains the draw method and then have your FunctionBlock class implement it:

    interface Drawable {
        /** Draws the block */
        void draw();
    }
    
    public abstract class FunctionBlock implements Drawable {
    

    If not every FunctionBlock class defines a draw() method, then you can have the individual subclasses implement the interface instead. If this is the case, you just have to change the type of block to Drawable