Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I don't want to use "instanceof" in java , what do I do?

I have two abstract classes called Robot and GeometricElement. Each one of them has subclasses. I need to build a matrix of NxM that holds either a Robot or a GeometricElement, so I've written another class and called it Item, and then Robot and GeometricElement inherit from that class.

Here is the code:

public class Item {
    private Dot currentLocation;
    private boolean taken;

    public Item(Dot location) {
        int x = location.getXcomponent();
        int y = location.getYcomponent();
        currentLocation = new Dot(x,y);
        taken = false;
    }

    // more code 
}

public abstract class GeometricElement extends Item {

    private float area; 

    public GeometricElement(Dot location) {
        super(location);
    }
}


public abstract class Robot extends Item { 
    private float basketArea;

    /*  Constructor */

    public Robot(Dot location, float basketNewArea) {
        super(location);
        basketArea = basketNewArea;
    }

    // some more code 
}

The class that takes care of storing the Items is called Ground :

public class Ground {

    private Item[][] board;
    private Queue elementQueue;

    /*  Constructor */

    public Ground(int row,int col) {
        board = new Item[row][col];
        this.elementQueue = new Queue();
    }

    // more code 

    public void addElementsToRobot() {
        while (this.elementQueue.doesQueueHasItems()) {
            GeometricElement element = elementQueue.popElementFromQuque();
            int x = element.getXlocation();
            int y = element.getYlocation();
            if (this.board[x][y].isTaken()) {
                if (board[x][y] instanceof Robot) {
                    // add geometric element to the basket
                }
            }
        }
    }
}

As mentioned above, I need to store a Robot or a GeometricElement in the board. The problem starts when I try to read from the matrix (the 'board' matrix in 'Ground'): I can't seem to find a way to tell if I have in a cell either a Robot or a GeometricElement, without using instanceof.

like image 875
JAN Avatar asked Jan 23 '26 10:01

JAN


2 Answers

I don't know your goals of course, but from the top of my head:

I would personally refactor this using Composite pattern, so that you can access all elements in a uniform fashion. And as for determining without instance of, you can have an abstract method on your Item class telling each other apart. Or you could have public property doing that. Or you could come with better design.

It really depends on what you are trying to achieve. Instanceof may be actually a solution to your problem but generally, it points to deeper design issue.

like image 71
Tomáš Plešek Avatar answered Jan 25 '26 23:01

Tomáš Plešek


Here are some alternatives, using the Class object returned by Object.getClass():

  • Use Class.isAssignableFrom(Class) to test if the Class object is a subclass of (say) Robot.

  • Compare it with the Class objects for the leaf classes.

  • Do some stuff with the String returned by Class.getName(), etcetera.

Or you could add an abstract method boolean isARobot() to the Item class.

Or you could define an enum whose values denote the direct subclasses of Item.

However, these are all doing pretty much the same thing as instanceof ... so (IMO) you haven't achieved anything. Certainly, you haven't removed the "code smell" of using instanceof.

like image 37
Stephen C Avatar answered Jan 26 '26 00:01

Stephen C