Java从Object转换为Subclass

db2*_*791 10 java oop inheritance types class

这是我的Scene.java代码.它有不同类型的对象,所有这些对象都包含在一个常见的ArrayList中targets.所有这些都共享一个toString()返回其标识符的方法.我想使用targets列表来确定场景中是否有任何与给定标识符匹配的对象,无论其类型如何:

ArrayList<NPC> npcs = new ArrayList<NPC>();
ArrayList<Item> items = new ArrayList<Item>();
ArrayList<EnviromentalObject> enviromental_objects = new ArrayList<EnviromentalObject>();

ArrayList<Object> targets;

public Object check_for_target(String target_name){
    targets.addAll(npcs);
    targets.addAll(items);
    targets.addAll(enviromental_objects);
    for (Object target : targets){
        if (target.toString() == target_name){
            return target;
        }
    }
    return null;
Run Code Online (Sandbox Code Playgroud)

这是Game.java中的代码,它检查给定的标识符.如果当前场景存在匹配,我想知道对象的类型并将其视为真实类型.现在,我有以下代码,我知道它不会起作用,但也许它有助于我的想法.

Object target = current_scene.check_for_target(target_name);
        if (target == null){
            System.out.println(UNRECOGNIZED_TARGET_MESSAGE);
        } else {
            String target_type = target.getClass().getName();
            target = (target_type) target;
        }
Run Code Online (Sandbox Code Playgroud)

获取对象类型然后能够使用该对象的方法的正确方法是什么?现在,我只给出了Object方法.难道我创建一个超类NPC,ItemEnviromentalObject

Sir*_*ir1 14

基本上,您可以检查对象是否是特定类的实例.

它可能是这样的:

if( target instanceof NPC) {
    System.out.println("target  is a NPC");
}
else if( Target instanceof Item) {
    System.out.println("target is an Item");
}

if( target  instanceof EnviromentalObject) {

    System.out.println("target is EnviromentalObject"); 
}
Run Code Online (Sandbox Code Playgroud)

编辑:正如我们在评论中所说的那样,我认为您可以更改代码以获得更好的解决方案.上面的代码仍然有效,但使用被称为编程最佳实践的设计模式是一种非常好的做法.对于这种情况,请考虑使用java接口并定义每个对象可以根据需要实现它们的共享方法.用最简单的方式打印标识符.我们来举个例子:

public interface SceneThings() {

    public void printIdentifire();

    public String doSomeOtherThings();

}
Run Code Online (Sandbox Code Playgroud)

每个对象都可以通过以下方式实现上述接口:

public class Item implements SceneThing {

...

public void printIdentifire(){

//print its identifier here.
System.out.print("ID:ITEM###");

}

public String doSomeOtherThings(){

    //do some other works !!!
}
...
}
Run Code Online (Sandbox Code Playgroud)

对于与上述相同的其他项目.然后你可以使用一个数组来保存它们而不用担心它们的原始类如下:

ArrayList<SceneThings> targets = new ...

SceneThing  obj = new Item();
targets.add(obj);
Run Code Online (Sandbox Code Playgroud)

我希望这可以帮助您在您的案例中定义更好的解决方案.

  • @SeanScott好吧,假设可以成为目标的类的数量随着时间的推移而增长.然后你将不得不添加越来越多的`if(target instanceOf SomeClass)`语句,这使得维护非常困难.使用接口或抽象类,您不必再次触摸它. (3认同)

erk*_*fel 7

声明超类或接口Target并使用它来保持目标数组的方法之一是使用抽象类的完整代码示例:

ArrayList<NPC> npcs = new ArrayList<NPC>();
ArrayList<Item> items = new ArrayList<Item>();
ArrayList<EnviromentalObject> enviromental_objects = new ArrayList<EnviromentalObject>();

ArrayList<Target> targets;

public Target check_for_target(String target_name) {
    targets.addAll(npcs);
    targets.addAll(items);
    targets.addAll(enviromental_objects);
    for (Target target : targets) {
        if (target.toString().equals(target_name)) {
            return target;
        }
    }
    return null;
}

private abstract class Target {}
private class NPC extends Target {}
private class Item extends Target {}
private class EnviromentalObject extends Target {}
Run Code Online (Sandbox Code Playgroud)

  • 我几乎同意(参见我对Q的评论),但会使用Interfaces而不是超类.无论如何,因为这是比无休止的`instanceof`s更好的方法. (3认同)