4

我有一组具有共同超类的 POJO。它们存储在superclass类型的二维数组中。现在,我想从数组中获取一个对象并使用子类的方法。这意味着我必须将它们强制转换为subclass。有没有办法在不使用instanceof的情况下做到这一点?

更新:作为一个具体示例: http: //obviam.net/index.php/the-mvc-pattern-tutorial-building-games/请参阅:“单击敌人时添加新动作(攻击)”

4

5 回答 5

6

是的 - 您可以通过反转流程来做到这一点:当基类的实例是特定类型时,您的代码不会做某事,而是将操作项传递给对象,并让对象决定是否执行它。这是访问者模式背后的基本技巧。

interface DoSomething {
    void act();
}
abstract class AbstractBaseClass {
    abstract void performAction(DoSomething ds);
}
class FirstSubclass extends AbstractBaseClass {
    public void performAction(DoSomething ds) {
        ds.act();
    }
}
class SecondSubclass extends AbstractBaseClass {
    public void performAction(DoSomething ds) {
        // Do nothing
    }
}

AbstractBaseClass array[] = new AbstractBaseClass[] {
    new FirstSubclass()
,   new FirstSubclass()
,   new SecondSubclass()
,   new FirstSubclass()
,   new SecondSubclass()
};
for (AbstractBaseClass b : array) {
    b.performAction(new DoSomething() {
        public void act() {
            System.out.println("Hello, I'm here!");
        }
    });
}
于 2012-07-10T14:09:23.650 回答
4

如果您知道它们是子类类型,那么只需直接转换它们而无需instanceof检查。

但是将它们放在超类类型的数组中是告诉编译器丢弃它们实际上是子类类型的信息。要么你的超类应该公开这些方法(可能是抽象的),要么你的数组应该是子类类型(所以你不会告诉编译器忘记对象的实际类型),或者你必须把它吸干并做演员(可能与instanceof测试)。

唯一值得注意的替代方案是您可以尝试使用访问者模式,该模式将操作传递给对象并让对象决定如何处理它。这使您可以覆盖类以根据其运行时类型忽略或执行操作。

于 2012-07-10T14:08:26.103 回答
2

您可以尝试使用访问者设计模式。 http://en.wikipedia.org/wiki/Visitor_pattern

你要问自己,为什么你需要知道它们的类型,也许这可以用超类中的抽象方法来代替,每个人都可以根据想要的结果来实现。

abstract class A{
    abstract void visit();
}

class B extends A{
    void visit() { print("B"); }
}

class C extends A {
    void visit() { print("C"); }
}
于 2012-07-10T14:09:49.300 回答
1

我会避免首先铸造它们。

真正考虑一下您要做什么,以及它们是否应该像这样在同一个集合中。

如果你有这样的事情

for(MyObj o : array) {
   if(o instanceof A) {
      ((A)o).doA();
   }
   if(o instanceof B) {
      ((B)o).doB();
   }
}

考虑一下

abstract class MyObj {
    abstract void doIt();
}

class A {
    void doIt() { doA(); }
}

class B {
    void doIt() { doB(); }
}
于 2012-07-10T14:11:39.023 回答
0

在超类中公开方法,然后使用覆盖。在基类中提供一个空实现,以便子类可以在需要时忽略该操作。

于 2012-07-10T14:12:53.423 回答