Могу ли я иметь разные копии статической переменной для каждого другого типа наследуемого класса
-
11-09-2019 - |
Вопрос
Я хочу иметь одну и ту же статическую переменную с разным значением в зависимости от типа класса.
Так что я бы
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
{
}
А затем в моей основной программе перейдите:
Marine.sprite = // Load sprite for all instances of Marine
Genestealer.sprite = // Load sprite for all instances of Genestealer
Я не хочу хранить один и тот же спрайт в каждом экземпляре класса.Я хочу по одному для каждого типа класса.Я хочу наследовать статическую переменную sprite и функцию draw, которая будет рисовать sprite.Но я не хочу, чтобы спрайт Genstealer переопределял спрайт Marine.
Возможно ли это?
Как бы я это сделал?
Решение
Используйте абстрактный метод:
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*/;
}
}
Спрайт, возвращаемый getSprite, может быть статическим, если хотите.Приятные моменты в этом подходе:
Вы не можете (легко) забыть включить спрайт в свой подкласс, поскольку компилятор будет жаловаться, если вы не реализуете абстрактный метод.
Это гибкий подход.Предположим, морской пехотинец должен выглядеть по-другому, как только он "повысит уровень".Просто измените метод getSprite в Marine, чтобы учесть уровень.
Это стандартная OO-идиома для подобных вещей, так что людям, просматривающим их код, не придется ломать голову.
Другие советы
Это невозможно, чтобы это было статично в суперклассе.Эта статическая переменная в суперклассе является общей (фактически синглтоном) для всех подклассов.Всякий раз, когда вы изменяете это (скажем, создавая экземпляр подкласса), это изменение отражается во всех других экземплярах подкласса.
Вместо этого сделайте спрайт статичным в подклассах, а затем используйте структуру метода, описанную Лоуренсом.
У меня был тот же вопрос, и я пришел к решению использовать статическое отображение
Класс -> Объект.
Следующий пример кода использует Integer в качестве типа желаемой переменной "class-static".
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 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
Я надеюсь, что это кому-то поможет.Пожалуйста, будь добр.
Поэтому создайте один спрайт и раздайте всем переменные экземпляра.Это просто ссылки;едва ли больше, чем указатели.
Быстрый тест покажет вам, что да, вы можете переопределять статические переменные в подклассах.
Я собрал простую структуру наследования, чтобы проверить это.StaticTest - это суперкомпьютер StaticTestSub.Они оба объявляют статические целые числа TEST1
, TEST2
, и TEST3
с разной степенью доступа.Чтобы упростить пример, я опустил private
версия.
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;
}
Вы можете попробовать это дома.Выход из положения был:
Статический тест.ТЕСТ1:1
Статический тест.ТЕСТ2:1
Статический тест.ТЕСТ3:1
StaticTestSub.ТЕСТ1:2
StaticTestSub.ТЕСТ2:2
StaticTestSub.ТЕСТ3:2
Однако для ваших конкретных нужд я рекомендую подход Лоуренса Гонсалвеса