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

时间:2011-12-10 14:23:52

标签: java inheritance abstract-class

我有两个名为RobotGeometricElement的抽象类。 它们中的每一个都有子类。 我需要构建一个NxM矩阵,它包含RobotGeometricElement,所以 我写了另一个类并将其称为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。当我尝试从矩阵中读取时,问题就开始了('Ground'中的'board'矩阵):我似乎找不到一种方法来判断我是否在单元格中有Robot或GeometricElement,而不使用{ {1}}。

5 个答案:

答案 0 :(得分:1)

我当然不了解你的目标,但从头到尾:

我会亲自使用Composite模式重构它,以便您可以以统一的方式访问所有元素。至于确定没有实例,你可以在你的Item类上有一个抽象的方法,相互分开。或者你可以让公共财产这样做。或者你可以选择更好的设计。

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

答案 1 :(得分:1)

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

  • 使用Class.isAssignableFrom(Class)来测试Class object是否是(例如)Robot的子类。

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

  • 使用Class.getName()等返回的字符串执行一些操作。

或者您可以向boolean isARobot()类添加抽象方法Item

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

然而,这些都与instanceof完全相同......所以(IMO)你没有取得任何成就。当然,您还没有删除使用instanceof的“代码味道”。

答案 2 :(得分:1)

我喜欢使用Composite设计模式的想法。很优雅:))

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

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

但是,你必须小心避免在两个矩阵的坐标上都有东西。

正如我所说,更不优雅,但仍然没有实例:)

答案 3 :(得分:1)

鉴于这是家庭作业,'instanceof'是最简单的,因此可能是最好的方式,即使它根本不是面向对象的,并且绝对是代码味道。

一种更先进的方法是使用'双重发送',a.k.a。访客模式。在http://www.javaworld.com/javaworld/javatips/jw-javatip98.html

有一个很好的解释

答案 4 :(得分:0)

我的建议绝对是你必须使用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
 }