MatthewMcGovern
MatthewMcGovern

Reputation: 3496

Child class overwriting parent class variable?

I have a class "Unit" that holds functions and variables that all Units in my game will share. I have then extended it with a "Soldier" class. Unit has a static variable that holds the base texture (as it will be the same for all units of that type when created, textures may change over time). These are loaded by:

Unit.baseTexture = content.Load<Texture2D>("worker");
Soldier.baseTexture = content.Load<Texture2D>("soldier");

When a "Unit" is created from the "Unit" constructor, it will load the texture with:

this.texture = Unit.baseTexture;

When a "Soldier" is created, it will load it like this:

this.texture = Soldier.baseTexture;

texture is a protected variable, not static so it should be one per object.

In the main game logic, I have an ArrayList that has multiple Unit and Soldier objects stored in it.

When I loop through them, I am doing:

foreach (Unit unit in unitList)
{
    unit.Draw(spriteBatch);
}

Draw is a function on the Unit class:

spriteBatch.Draw(this.texture, this.position, Color.White);

However, this is causing all units to draw with the last loaded texture (in this case, the soldier texture). This confuses me as I called the parent class first, then the child class. Why has loading the Soldier texture changed the Unit texture as well, if what gets drawn is a texture per object?

Upvotes: 1

Views: 2539

Answers (2)

JLRishe
JLRishe

Reputation: 101672

I think the correct thing to do here is use a property for BaseTexture, and then you can override it as needed, by using the override keyword. Use of the new keyword to hide members should be avoided.

For example:

class Unit
{
   private static Texture2D s_unitTexture = content.Load<Texture2D>("worker");
   protected virtual Texture2D BaseTexture
   {
      get { return s_unitTexture; }
   }

   public Texture2D Texture { get; set; }

   public Unit()
   {
       this.Texture = BaseTexture;
   }

   ...
}

class Soldier : Unit
{
   private static Texture2D s_soldierTexture = content.Load<Texture2D>("soldier");
   protected override Texture2D BaseTexture
   {
      get { return s_soldierTexture; }
   }

   ...
}

This way, when the constructor runs, the right BaseTexture for each type of Unit will be used.

Upvotes: 1

MatthewMcGovern
MatthewMcGovern

Reputation: 3496

Oh man, I'm an idiot. I solved this as soon as I posted.

The child class Soldier was not defining its own baseTexture variable, so when I was loading the soldier texture with Soldier.baseTexture, it was actually using Unit.baseTexture.

Should I be using an interface instead of a base class? To make sure all my classes have a correct load function and variable? Otherwise I have to keep using "new" when making my child objects to force it to override a static variable.

Upvotes: 0

Related Questions