Reputation: 960
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.
Upvotes: 0
Views: 190
Reputation: 200138
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.
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"; }
...
Upvotes: 3
Reputation: 69
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");
}
Upvotes: 2