Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java converting from Object to Subclass

Here is my code for Scene.java. It has different types of objects, all of which are included in one common ArrayList called targets. All of them share a toString() method that returns their identifier. I want to use the targets list to determine if there is any object in the scene that matches a given identifier, regardless of its type:

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;

Here is the code in Game.java, which checks for a given identifier. If there is a match ion the current scene, I want to know the object's type and treat it as its true type. Right now, I have the following code, and I knew it wouldn't work, but maybe it'll help get my idea across.

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;
        }

What would be the correct way of getting the object's type and then being able to use that object's methods? Right now, I'm only given Object's methods. Do I create a superclass for NPC, Item, and EnviromentalObject?

like image 869
db2791 Avatar asked May 26 '16 17:05

db2791


2 Answers

Basically, you can check if an object is an instance of a specific class.

it could be something like this :

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"); 
}

Edit: as we talked in the comments I think you can change your code to reach a better solution. The above code is still works but it can be a very good practice to using Design Patterns that are known as best practices in programming. For this situation think about using java interface and define share methods that each object could implements them by its need. In the simplest way they print their identifier. Let's use an example :

public interface SceneThings() {

    public void printIdentifire();

    public String doSomeOtherThings();

}

Each object can implements the above interface by it needs like :

public class Item implements SceneThing {

...

public void printIdentifire(){

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

}

public String doSomeOtherThings(){

    //do some other works !!!
}
...
}

for other items same as above. And then you can use a single array to keep them without worry about their origin class like this:

ArrayList<SceneThings> targets = new ...

SceneThing  obj = new Item();
targets.add(obj);

I hope this can help you to define a better solution in your case.

like image 111
Sir1 Avatar answered Nov 15 '22 23:11

Sir1


One of the ways how it could be done it to declare a superclass or interface Target and use it to keep targets array, the full code sample with abstract class:

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 {}
like image 7
erkfel Avatar answered Nov 16 '22 01:11

erkfel