Fluidic Ice
Fluidic Ice

Reputation: 65

Unknown parent variable issue in java

Recently I asked a question about why all my variables in spawned items were being set to the same damage value (Java switch statements outputting the same numbers) and that code wasn't to blame, however after some deep debugging i've found that when an item is spawned it randomises the damage and then for some reason sets that damage to every previously created item of the same type.

I have 'dagger' and 'sword' classes which extend my 'item' class. This is how I set the damage:

case 3: {Sword sword = new Sword(); World[X][Y].treasureName = "sword"; sword.setDamage(4); returnItem = sword; break;}

And this is my item class:

public abstract class Item {
//How much damage is added to the players attack.
static int damage = 0;
static int defence = 0;

public int getDefence() {
    return defence;
}

public void setDefence(int defenceValue) {
    defence = defenceValue;
}

public int getDamage() {
    return damage;
}

public void setDamage(int damageValue) {
    damage = damageValue;
}
}

And my sword class:

public class Sword extends Item { 
//How much damage is added to the players attack.
static int damage = 0;
static int defence = 0;

public int getDefence() {
    return defence;
}

public void setDefence(int defenceValue) {
 defence = defenceValue;
}

public int getDamage() {
    return damage;
}

public void setDamage(int damageValue) {
    damage = damageValue;
}
}

I'm not sure what this problem is called and not sure what to google being fairly new still. I tried to override the item class but that didn't change anything and i've read about inheritance and I don't understand which part is setting every other weapon instance to the same damage. I wanted to remove the methods in the 'Item' class to see if that would fix it, however other code causing errors prevented me to do this when checking and adding together the damage of all the children of 'Item' - this required a cast of (Item) and i'm not sure of what else I can use as a cast.

Here are the referrals to the 'Item' method:

if (((Item) World[k][i].treasure).getDamage() > 9)
                            {

Without the cast the error is: getDamage() is undefined for the type Object. and:

//Recalculates the players damage for recently equipped items.
        for (int i = 0; i < numItems; i++) {
            itemdamage += items[i].getDamage();
            System.out.println("You have a " + itemNames[i] + " giving you " + items[i].getDamage() + " extra damage.");
            }

What's wrong? I want to understand this so links to helpful information on why, and what i'm doing wrong would be good. Thanks.

Upvotes: 1

Views: 144

Answers (5)

Andy Ruiz
Andy Ruiz

Reputation: 29

Heyhey Fluidic,

I'm still fairly new to Java myself, but I think your problem is that your damage variables are set to static (and I would assume the problem would persist across your defence stats as well!)

I had this problem while learning to develop in C++. I would change a value of one of my constructors which referenced a static variable, and all of the instances would change. It's a constant belonging to the class itself, not the object.

So what's happening, is when you change the damage value; all references that use that static damage variable are being changed.

This site gives a bit of an insight on static variables! http://www.javatpoint.com/static-keyword-in-java

Lemme know if that helps!

Andy

Upvotes: 2

dimo414
dimo414

Reputation: 48804

Your damage and defense variables should not be static. A static variable is tied to the whole class, not to any one instance of the class. As such, when you call setDamage(), even though the method is an instance method, it updates a static variable which is shared by every existing instance.

Remove the static (did you mean to use protected?) and you won't see the "for some reason sets that damage to every previously created item of the same type" behavior anymore.

See What does the 'static' keyword do in a class? for more. Here's the official Java Language Specification on static fields, as well.

Upvotes: 4

Vyncent
Vyncent

Reputation: 1205

According to the error :

getDamage() is undefined for the type Object

I think you World array, is an array of Object instead of Item

Could you show us how you manage the World array ?

Upvotes: 1

Nir Alfasi
Nir Alfasi

Reputation: 53525

You set the variables damage and defence (spelling mistake here - by the way) to be static. Which means that there's only one copy of each variables for the entire class.

Remove the static keyword before the declaration of both variables - and it'll make any new sword instance (object) - carry its own damage and defence.

Upvotes: 2

Eran
Eran

Reputation: 393781

static int damage = 0;

Having a static member means that all objects of the class same the same value. If you remove the static keyword, each object will be able to have a different value for damage.

As to the required cast, it seems that World is an array of Object type. Therefore World[k][i] is of Object type, and you can only call methods of the base Object class on it. If you want to call a method defined in the Item class, you must cast the Object to an Item (assuming the runtime type of that Object is an Item).

Upvotes: 5

Related Questions