0

I'm making a small RPG. There is an Item class which is the parent of each item in the game. These items could be Potion (which is a class) or Bandage (which is a class).

The Item class looks like this:

public class Item { int qty; String name; Hero hero1; public void passHero(Hero hero1) { this.hero1 = hero1; } public void use() { if(qty == 0) { System.out.println("You have no more of this item to use."); } else { qty--; } } public void addInv(int value) { qty = qty + value; } } 

A method for passing in the Hero class. A method for using an item. A method for adding to the inventory of the item.

This method activates these item classes:

public void initializeItemInventory() { items[0] = new Potion(); items[1] = new Bandage(); } 

And this method would theoretically print all the items and their quantities:

public void useInventory() { for(int i = 0; i<items.length; i++) { System.out.println("Enter: " + i + " for " + items[i].name); } int response = input.nextInt(); items[response].use(); } 

The Potion class, as an example, has an instance variable like:

String name = "Potion"; 

So my question. Why isn't the name variable from Potion being called correctly in the useInventory method. It returns null which tells me it's returning the parent class Item name, and not the name of the individual subclass variables.

12
  • 3
    possible duplicate of Java inheritance overriding instance variable Commented Feb 17, 2015 at 19:27
  • @aruisdante suggestions? Commented Feb 17, 2015 at 19:28
  • 1
    Side note on your design: do you think that an item owns a hero? Commented Feb 17, 2015 at 19:29
  • 1
    Read the duplicate question and its answers. And the other question and its answers that the duplicate is a duplicate of. If you're still unclear, add additional details to your question as to what in those duplicates don't answer your question. Commented Feb 17, 2015 at 19:29
  • Well, the first question that came to my mind is: why does the Item care about Hero? A hero might "know" his inventory, but the Item shouldn't care about his carrier. Commented Feb 17, 2015 at 19:30

2 Answers 2

3
public class Item { int qty; String name; ... 

The Item class already has name, and that's what you access from an Item-typed variable:

items[0].name 

So if you have

public class Potion extends Item { String name = "Potion"; ... 

then the Potion class has two name fields:

Potion p = new Potion(); System.out.println(p.name); System.out.println((Item) p).name); 

As you say, you want polymorphism, but it only applies to methods. Therefore you need a getter:

public class Item { String name; public String getName() { return name; } ... 

In the Potion subclass you may have

public class Potion extends Item { public Potion() { this.name = "Potion"; } ... 

and items[0].getName() will now work as expected.

Additional note

I'll add this to show a bit of the power of polymorphism.

If you happened to have the name property always the same for all the instances of the same class, you could easily refactor your getter-based solution by completely eliminating the need to store a name variable:

public class Item { public String getName() { return "Generic item"; } ... 

public class Potion extends Item { @Override public String getName() { return "Potion"; } ... 
Sign up to request clarification or add additional context in comments.

Comments

2

Instead of declaring a new variable in your subclass like "String name = "Potion";" Use your constructor to pass the value to your superclass, something like this:

// the Item supuerclass has one constructor public Item(name) { this.name = name; } // the Potion subclass has one constructor public Potion() { super("Potion"); } 

1 Comment

The downside to this approach is that you now have a duplicate name string in every Item class instance, even though they all point to the same object. This would make sense if name was relatively unique per item. If they're basically just a duplication of the class name however (as in the OP's design), it would more efficient to just have a single static name shared by all instances of the class.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.