0

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

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

例如

class A

class B extends A

class C extends A

class D extends A

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

现在,当它们出现时,我想将它们转换回原始类型以使用特定的方法/变量等。我怎样才能做到这一点而不必通过一组if语句来尝试找出它的子类类型是?它使我的代码非常不灵活,因为每次我添加一个扩展类 A 的新类时,我都必须编写一组新的if语句。有没有办法简单地返回对象所在类的确切名称?

4

2 回答 2

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());

将打印:


编辑

您在评论中描述的用例可以通过多种方式处理。最灵活的可能是多重调度模式(与访问者模式相关):

  1. 定义一个接口

    公共接口 SpriteActor { void actOn(A anASprite); 无效动作(B aBSprite);// ETC。 }

  2. 在 中定义一个方法A

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

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

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

于 2012-07-08T19:40:48.583 回答
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();
}
于 2012-07-08T20:14:49.623 回答