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 stat
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.
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.
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