我不想使用“instanceof”在java中,我该怎么办?

发布于 2024-12-20 08:02:01 字数 1952 浏览 1 评论 0原文

我有两个名为 RobotGeometricElement 的抽象类。 它们中的每一个都有子类。 我需要构建一个 NxM 矩阵,其中包含一个 Robot 或一个 GeometricElement,所以 我编写了另一个类并将其命名为 Item,然后命名为 RobotGeometricElement 从该类继承。

代码如下:

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 
}

负责存储 Item 的类称为 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
                }
            }
        }
    }
}

如上所述,我需要存储 RobotGeometricElement< /代码> 在板上。当我尝试从矩阵(“地面”中的“板”矩阵)读取时,问题就开始了:我似乎无法找到一种方法来判断单元格中是否有机器人或几何元素,而不使用 <代码>实例。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

記憶穿過時間隧道 2024-12-27 08:02:02

我的最终建议是您必须使用instanceof。

但另一种选择可能是:

 Object obj = ... //Robot or GeometricElement
 try {
     Robot robot =  (Robot) obj;
     // Do your logic for robot here
 } catch (ClassCastException ex){
     GeometricElement ge = (GeometricElement) obj;
     // Do your logic for geometric element here
 }

Definitively my recommendation is that you MUST use instanceof.

But an alternative may be:

 Object obj = ... //Robot or GeometricElement
 try {
     Robot robot =  (Robot) obj;
     // Do your logic for robot here
 } catch (ClassCastException ex){
     GeometricElement ge = (GeometricElement) obj;
     // Do your logic for geometric element here
 }
_畞蕅 2024-12-27 08:02:01

我当然不知道你的目标,但从我的想法来看:

我个人会使用复合模式重构它,以便你可以以统一的方式访问所有元素。至于在没有实例的情况下进行确定,您可以在 Item 类上使用一个抽象方法来区分彼此。或者你可以让公共财产来做这件事。或者你可以有更好的设计。

这实际上取决于您想要实现的目标。 Instanceof 实际上可能是您问题的解决方案,但一般来说,它指向更深层次的设计问题。

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.

妖妓 2024-12-27 08:02:01

以下是一些替代方案,使用 Object.getClass() 返回的 Class 对象:

  • 使用 Class.isAssignableFrom(Class) 进行测试如果 Class 对象 是(例如)Robot 的子类。

  • 将其与叶类的 Class 对象进行比较。

  • Class.getName() 返回的字符串做一些事情,等等。

或者,您可以将抽象方法 boolean isARobot() 添加到 Item 类。

或者,您可以定义一个 enum,其值表示 Item 的直接子类。

然而,这些都与 instanceof 做几乎相同的事情......所以(IMO)你还没有取得任何成果。当然,您还没有消除使用 instanceof 的“代码味道”。

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.

差↓一点笑了 2024-12-27 08:02:01

我喜欢使用复合设计模式的想法。非常优雅:)

一种不太优雅(但更快 - 可能是可取的,具体取决于你的作业何时到期)的方法是管理两个矩阵,一个用于机器人,一个用于几何对象。

使用这些,您可以通过检查哪个矩阵占用了该字段来轻松确定给定坐标处的项目是其中一个还是另一个。

不过,您必须小心避免在两个矩阵中的这些坐标上都有某些内容。

正如我所说,不太优雅,但仍然没有 instanceof :)

I like the idea of using the Composite design pattern. Very elegant :)

A less elegant (but faster - may be desirable, depending on when your homework's due) way would be to manage two matrices, one for Robots and one for GeometricObjects.

Using those, you could easily determine whether the Item at the given coordinates is one or the other by checking which matrix has that field occupied.

You'd have to be careful to avoid having something on those coordinates in both matrices, though.

As I said, much less elegant, but still no instanceof :)

长亭外,古道边 2024-12-27 08:02:01

鉴于这是家庭作业,“instanceof”是最简单的,因此可能是最好的方法,尽管它根本不是面向对象的,而且绝对是一种代码味道。

一种更高级的方法是使用“双重调度”,又称访客模式。 http://www.javaworld.com/javaworld/javatips 有一个很好的解释/jw-javatip98.html

Given that this is homework, 'instanceof' is the simplest, and therefore probably the best way to go, even though it's not at all object-oriented, and is definitely a code smell.

One, more advanced way to do this is with 'double dispatch', a.k.a. The Visitor Pattern. There's a pretty good explanation at http://www.javaworld.com/javaworld/javatips/jw-javatip98.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文