[英]avoiding instanceof
我有一组具有共同超类的POJO。 它们存储在类型超类的二维数组中。 现在,我想从数组中获取一个对象并使用子类的方法。 这意味着我必须将它们转换为子类 。 有没有办法在不使用instanceof的情况下执行此操作?
更新:作为一个具体的例子: http : //obviam.net/index.php/the-mvc-pattern-tutorial-building-games/请参阅: “点击敌人时添加新动作(攻击)”
是的 - 您可以通过反转流来完成:当基类的实例是特定类型时,代替您的代码执行操作,将操作项传递给对象,并让对象决定是否执行它。 这是访客模式背后的基本技巧。
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!");
}
});
}
如果您知道它们属于子类类型,那么只需直接转换它们而不进行instanceof
检查。
但是将它们放在一个超类型数组中告诉编译器丢弃它们实际上属于子类类型的信息。 您的超类应该公开那些方法(可能是抽象的),或者您的数组应该是子类类型(因此您不会告诉编译器忘记对象的实际类型),或者您必须将其吸收并执行转换(可能使用instanceof
测试)。
唯一另一个值得注意的替代方案是您可以尝试访问者模式,该模式将操作传递给对象并让对象决定如何处理它。 这允许您覆盖要忽略的类或根据其运行时类型执行操作。
您可以尝试使用访问者设计模式。 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"); }
}
我会避免在第一时间施放它们。
真的想想你要做什么,以及它们是否应该在同一个系列中。
如果你有类似的东西
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(); }
}
在超类中公开该方法,然后使用重写。 在基类中提供一个空实现,以便子类可以在需要时忽略该操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.