Могу ли я иметь разные копии статической переменной для каждого другого типа наследуемого класса

StackOverflow https://stackoverflow.com/questions/1448092

Вопрос

Я хочу иметь одну и ту же статическую переменную с разным значением в зависимости от типа класса.

Так что я бы

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

Однако для ваших конкретных нужд я рекомендую подход Лоуренса Гонсалвеса

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top