0

For a project I'm working on, I must implement a text based map which a player can navigate, interacting with certain objects on the map. Each time the player (user) picks up or puts down an object, the player's inventory is (supposed to be) displayed, for which I have written the following code:

ArrayList<GamePiece> inventory = new ArrayList<GamePiece>();

public String toString() {
    String result = "";
    for(int i = 0; i < inventory.size(); i++){
        result += " " + inventory.get(i);
    }
    return result;
}

I am overriding the toString method so I can print out the elements in the ArrayList, but each time I do it simply prints the memory location. For instance, if I have a Pebble and a Stone in my inventory, and I call this method, it returns the following:

[Pebble@75b84c92, Stone@6bc7c054]

I think I'm doing something wrong in the toString method, I just can't figure it out. If you have any ideas I'd love to hear them, you were a great help with my last question so I have confidence!

Here is my Pebble class:

public class Pebble extends Rock {
    private int pebbleWeight= 1;

    public Pebble() {
    }
    public char charRepresentation() {
        return 'P';
    }
    public String look() {
        return "This object is very small, with rounded edges and speckled with dark colors.";
    }

    public String touch() {
        return "Edges, shaped by millions of years of running water, are smooth.";
    }
    public int getWeight() {
        return pebbleWeight;
    }
    public String getName() {
        return "Pebble";
    }
}

Here is the Stone class:

public class Stone extends Rock {
    private int stoneWeight = 4;
    public Stone() {

    }
    private int weight= 1;


    public char charRepresentation() {
        return 'S';
    }

    public String look() {
        return "This object is about the size of your fist, with rounded edges and dark colors.";
    }

    public String touch() {
        return "Edges, shaped by millions of years of running water, are smooth. Not too heavy...";
    }
    public int getWeight() {
        return stoneWeight;
    }
    public String getName() {
        return "Stone";
    }
}

Rock class:

public class Rock extends GamePiece {

    public Rock() {
    }


    public String listen() {
        return "This object has no sound...";
    }

}

GamePiece class:

public class GamePiece {
    private int weight = 0;
    private int x = 0;
    private int y = 0;

    public GamePiece() {
    }
    public int getWeight() {
        return weight;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public char charRepresentation() {
        return '?';
    }
    public String look() {
        return "no description known";
    }
    public String listen() {
        return "no voice yet";
    }
    public String touch() {
        return "no texture yet";
    }
    public String getName() {
        // TODO Auto-generated method stub
        return null;
    }
}
  • 2
    Did you override toString() of Pebble and Stone classes? – eg04lt3r Oct 11 '16 at 17:59
  • Please post the relevant code of Pebble, Stone, and GamePiece – lucasvw Oct 11 '16 at 18:00
  • You have to implement toString on Pebble and Stone as well – ControlAltDel Oct 11 '16 at 18:00
  • Gamepiece is your base class correct? Do you override your the tostring method just in the extended classes? I am not sure if you need to overwrite the base class since you work with the base class as type – hasan Oct 11 '16 at 18:00
  • I did not override toString for any other classes, how would I go about implementing that in the for loop? I will upload all relevant code. – grateful_ted Oct 11 '16 at 18:14
  • You don't have to change anything within your for loop. To have your actual `GamePiece`s override the `toString()` method, you need to implement `toString()` inside of those classes. Otherwise, they are just using the default `toString()`, which as you can see does not do what you want. So for example, inside Pebble.java, have something like `@Override public String toString() { return "Pebble"; }` – jonhopkins Oct 11 '16 at 18:19
  • Could I override the getName method in each subclass, then add the string to the ArrayList? That seems like it might work... – grateful_ted Oct 11 '16 at 18:25
  • No. `ArrayList inventory` should continue to contain `GamePiece` objects. You already have implemented `getName()` in all the subclasses, except `Rock`. You can use this method in the loop, though. `result += " " + inventory.get(i).getName();` Since you just want to print out the names of the objects in the inventory, this could work well. The whole point of the `toString()` method is to provide a text representation of an object. So it could, for example, return a string containing the object's name, weight, position, and etc. – jonhopkins Oct 11 '16 at 18:29
  • I changed my for loop so it is now `for(GamePiece piece: inventory){` and then I used `result += " " + piece.getName()` and it is still returning the memory location. – grateful_ted Oct 11 '16 at 18:31
  • Did you recompile? At most, it should be returning `null` if you have any `GamePiece` or `Rock` objects in the inventory instead of only `Pebble` and `Stone` objects. – jonhopkins Oct 11 '16 at 18:35
  • Ok. Where is the location of the `toString()` method you posted, and how are you calling it? I just realized that it looks like you might be doing something like `System.out.println(inventory);` thinking that the `toString()` is related to the `ArrayList inventory`, which is _not_ what you want to do. I would recommend renaming it to `listInventory()` or something more meaningful, and then do `System.out.println(listInventory());` – jonhopkins Oct 11 '16 at 18:42

0 Answers0