Reputation: 65
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
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
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
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
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
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