Question

I want to have the same static variable with a different value depending on the type of class.

So I would have

public class Entity
{
     public static Bitmap sprite;

     public void draw(Canvas canvas, int x, int y)
     {
          canvas.drawBitmap(sprite, x, y, null);
     }
}

public class Marine extends Entity
{

}

public class Genestealer extends Entity
{

}

And then in my main program go:

Marine.sprite = // Load sprite for all instances of Marine
Genestealer.sprite = // Load sprite for all instances of Genestealer

I don't want to store the same sprite in every instance of the class. I want one for each type of class. I want to inherit the static sprite variable and the draw function which will draw the sprite. But I don't want the Genstealer sprite to override the Marine sprite.

Is this possible?

How would I do it?

Was it helpful?

Solution

Use an abstract method:

public class Entity
{
     public abstract Bitmap getSprite();

     public void draw(Canvas canvas, int x, int y)
     {
          canvas.drawBitmap(getSprite(), x, y, null);
     }
}

public class Marine extends Entity
{
    public Bitmap getSprite() {
        return /*the sprite*/;
    }
}

The sprite returned by getSprite can be a static if you like. Nice things about this approach:

  • You can't (easily) forget to include a sprite in your subclass, since the compiler will complain if you don't implement the abstract method.

  • It's flexible. Suppose a Marine should look different once he "levels up". Just change Marine's getSprite method to take the level into account.

  • It's the standard OO-idiom for this sort of thing, so people looking at their code won't be left scratching their heads.

OTHER TIPS

It's not possible for it to be static in the super class. That static variable in the super class is shared (effectively a singleton) by all the sub classes. Anytime you change that (say, by instantiating a sub class), that change is reflected in all the other sub class instances.

Instead, make the sprite static in the subclasses, and then use the method structure described by Laurence.

I had the same question and came to the solution to use a static mapping

Class --> Object.

The following code example uses Integer as the type of the desired "class-static" variable.

import java.util.Map;
import java.util.HashMap;

class C
{
    static Map<Class<?>,  Integer> class2IntegerMap = new HashMap<Class<?>, Integer>();


    public void setClassSpecificInteger(Integer _i)
    {
        class2IntegerMap.put(this.getClass(), _i);
    }

    public Integer getClassSpecificInteger()
    {
        return class2IntegerMap.get(this.getClass());    
    }           
}

class CA extends C
{
}

class CB extends C
{
}

class CAA extends CA
{
}

public class MainClass
{
    public static void main(String []args)
    {
        CA a1 = new CA();
        CA a2 = new CA();
        CB b1 = new CB();
        CB b2 = new CB();
        CAA aa1 = new CAA();

        a1.setClassSpecificInteger(Integer.valueOf(-1));
        b1.setClassSpecificInteger(Integer.valueOf(+33));

        System.out.println("The int-value for a1 is: "+a1.getClassSpecificInteger());
        System.out.println("The int-value for b1 is: "+b1.getClassSpecificInteger());

        System.out.println("The int-value for aa1 is: "+aa1.getClassSpecificInteger());

        System.out.println("The int-value for a2 is: "+a2.getClassSpecificInteger());
        System.out.println("The int-value for b2 is: "+b2.getClassSpecificInteger());

        CA a3 = new CA();
        CB b3 = new CB();

        System.out.println("The int-value for a3 is: "+a3.getClassSpecificInteger());
        System.out.println("The int-value for b3 is: "+b3.getClassSpecificInteger());

        CAA aa2 = new CAA();

        aa2.setClassSpecificInteger(Integer.valueOf(8));

        System.out.println("The int-value for aa1 now is: "+aa1.getClassSpecificInteger());
    } 
} 

The output is:

The int-value for a1 is: -1
The int-value for b1 is: 33
The int-value for aa1 is: null
The int-value for a2 is: -1
The int-value for b2 is: 33
The int-value for a3 is: -1
The int-value for b3 is: 33
The int-value for aa1 now is: 8

I hope this helps someone. Please be kind.

So make one Sprite and give everyone instance variables. They are just references; hardly more than pointers.

A quick test will show you that, yes, you can override static variables in subclasses.

I have put together a simple inheritance structure to test this. StaticTest is the super of StaticTestSub. They both declare static ints TEST1, TEST2, and TEST3 with varying degrees of access. To simplify the example, I left out the private version.

public class StaticTest {
    public static int TEST1 = 1;
    protected static int TEST2 = 1;
    static int TEST3 = 1;

    public static void main(String[] args) {
            System.out.println("StaticTest.TEST1: " + StaticTest.TEST1);
            System.out.println("StaticTest.TEST2: " + StaticTest.TEST2);
            System.out.println("StaticTest.TEST3: " + StaticTest.TEST3);
            System.out.println("StaticTestSub.TEST1: " + StaticTestSub.TEST1);
            System.out.println("StaticTestSub.TEST2: " + StaticTestSub.TEST2);
            System.out.println("StaticTestSub.TEST3: " + StaticTestSub.TEST3);
    }
}


public class StaticTestSub extends StaticTest {
    public static int TEST1 = 2;
    protected static int TEST2 = 2;
    static int TEST3 = 2;
}

You can try this at home. The out put was:

StaticTest.TEST1: 1
StaticTest.TEST2: 1
StaticTest.TEST3: 1
StaticTestSub.TEST1: 2
StaticTestSub.TEST2: 2
StaticTestSub.TEST3: 2

For your specific needs, however, I recommend the approach taken by Laurence Gonsalves

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top