在没有if语句的情况下从数组中获取instanceof类型

时间:2012-07-08 19:34:20

标签: java

注意:这是我的问题的抽象版本,因为许多实际代码可能会令人困惑并且与问题无关。

我有一个对象的数组/ ArrayList,它们都从另一个类继承了它们的信息。

例如

class A

class B extends A

class C extends A

class D extends A

B,C和D类的对象都进入A类数组。

现在当它们出来时,我想将它们转换回原始类型以使用特定的方法/变量等。如何在不必浏览一组的情况下执行此操作语句试图找出它是什么类的子类?它使我的代码非常不灵活,因为每次添加新类时我都必须编写一组新的 if 语句扩展了A类。有没有办法简单地返回一个对象的类的确切名称?

2 个答案:

答案 0 :(得分:2)

如果您只想要对象类的名称,可以使用

a.getClass().getName(); // or .getSimpleName();

即使a被声明为超类的类型,这也会有效。假设您的问题中的类结构:

A a = new B();
System.out.println(a.getClass().getSimpleName());
a = new C();
System.out.println(a.getClass().getSimpleName());

将打印:

  


  ç

修改

您在评论中描述的用例可以通过多种方式处理。最灵活的可能是multiple dispatch pattern(与visitor pattern相关):

  1. 定义界面

    public interface SpriteActor {     void actOn(A anASprite);     void actOn(B aBSprite);     //等 }

  2. A中定义方法:

    公共类A {     public void acceptActor(SpriteActor actor){         actor.actOn(本);     } }

  3. 在每个Sprite子类中重写此方法。奇怪的是,您可以在每个覆盖中使用完全相同的代码。这是必要的,以便编译器将调用绑定到actOn实现的正确重载SpriteActor方法。

  4. 在您的客户端代码中,实现SpriteActor接口。在每个重载的actOn方法中实现特定于类型的调用。

答案 1 :(得分:1)

正如你所发现的那样,这很难看。你应该使用多态:

class A {
    public abstract void doStuff();
};

class B extends A {
    private void foo() { ... }  // Class-specific method
    @Override
    public void doStuff() { foo(); }
}

class C extends A {
    private void bar() { ... }  // Class-specific method
    @Override
    public void doStuff() { bar(); }
}

...

A[] array = { new B(), new C() };

// No casting or conditionals needed!
for (A a : array) {
    a.doStuff();
}