【问题标题】:Can I have different copies of a static variable for each different type of inheriting class我可以为每种不同类型的继承类拥有不同的静态变量副本吗
【发布时间】:2010-11-29 16:54:37
【问题描述】:

我希望根据类的类型拥有具有不同值的相同静态变量。

所以我会的

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

我不想在类的每个实例中存储相同的精灵。我想要一个用于每种类型的课程。我想继承静态精灵变量和绘制精灵的绘制函数。但我不希望 Genstealer 精灵覆盖 Marine 精灵。

这可能吗?

我该怎么做?

【问题讨论】:

  • 甚至你的 gravatar 也是穿着太空海洋盔甲的燕尾服企鹅 - 太棒了:)
  • 我想你也可以在父类中用“抛出新的 UnsupportedOperationException”来定义它,如果你有某些子类从没想过会有精灵(尽管这也意味着你会失去编译时间检查) .

标签: java inheritance static-variables


【解决方案1】:

使用抽象方法:

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 返回的精灵可以是静态的,如果你喜欢的话。这种方法的优点:

  • 您不能(轻易)忘记在子类中包含精灵,因为如果您不实现抽象方法,编译器会报错。

  • 它很灵活。假设一名海军陆战队员“升级”后看起来应该有所不同。只需更改 Marine 的 getSprite 方法以考虑关卡。

  • 这是此类事情的标准 OO 习惯用法,因此查看其代码的人不会摸不着头脑。

【讨论】:

    【解决方案2】:

    我有同样的问题,并找到了使用静态映射的解决方案

    类 --> 对象。

    以下代码示例使用 Integer 作为所需“类静态”变量的类型。

    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
    

    我希望这对某人有所帮助。请善待。

    【讨论】:

      【解决方案3】:

      在超类中不可能是静态的。超类中的静态变量由所有子类共享(实际上是单例)。任何时候您更改它(例如,通过实例化子类),该更改都会反映在所有其他子类实例中。

      相反,在子类中将 sprite 设为静态,然后使用 Laurence 描述的方法结构。

      【讨论】:

      • 这是原始问题的答案,其他答案必须得到相同的行为。但答案是否定的,C# 没有针对父类中定义的每个子类的静态变量的 anycon 构造。
      【解决方案4】:

      所以制作一个 Sprite 并给每个人实例变量。它们只是参考;只不过是指针而已。

      【讨论】:

        【解决方案5】:

        一个快速测试将告诉您,是的,您可以覆盖子类中的静态变量。

        我已经整理了一个简单的继承结构来测试它。 StaticTest 是 StaticTestSub 的上级。它们都声明了具有不同访问权限的静态整数 TEST1TEST2TEST3。为了简化示例,我省略了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;
        }
        

        你可以在家里试试这个。输出是:

        StaticTest.TEST1: 1
        静态测试.TEST2:1
        静态测试.TEST3:1
        StaticTestSub.TEST1: 2
        StaticTestSub.TEST2: 2
        静态测试子.TEST3:2

        但是,对于您的特定需求,我推荐 Laurence Gonsalves 采用的方法

        【讨论】:

          猜你喜欢
          • 2012-03-30
          • 2021-09-28
          • 2017-02-07
          • 1970-01-01
          • 2011-04-07
          • 2020-11-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多