是否使用静态块不良做法覆盖静态字段?

时间:2015-07-11 09:35:59

标签: java static subclassing

我想创建数据结构来捕获以下想法:

在游戏中,我希望有一个通用的Skill课程,可以捕捉技能ID,冷静时间,法术力费用等一般信息。

然后我想拥有定义实际互动和行为的特定技能。所以这些都将从基类Skill延伸。

最后,每个玩家都会拥有这些特定技能的实例,因此我可以检查每个玩家的技能状态,最近是否有玩家使用它等等。

所以我有一个抽象的超类Skill定义了一些静态变量,所有技能都有共同点,然后对于扩展Skill的每个技能,我使用静态块重新分配静态变量。所以我有以下模式:

class A {
    static int x = 0;
}

class B extends A {
    static {
        x = 1;
    }
}

...

// in a method
A b = new B();
System.out.println(b.x);

以上打印1,这正是我想要的行为。我唯一的问题是系统抱怨我以非静态方式访问静态变量。但当然我无法以这种方式访问​​它,因为我只想将技能视为Skill而不确切知道它是哪个子类。所以每次这样做时我都要压制警告,这让我想到这里是否有更好/更整洁的设计模式。

我考虑过让这些变量成为非静态变量,但是因为它们应该在特定技能的所有实例中保持静态,我觉得它应该是一个静态变量... < / p>

2 个答案:

答案 0 :(得分:2)

通常应该避免使用全局状态。如果您确定将在基类的所有子类型的所有实例之间共享字段import java.util.*; public class car{ public static void main(String[]args) throws java.io.IOException{ Scanner v = new Scanner(System.in); String model = new String(); double cost=0; System.out.print("Enter model: "); model = System.console().readLine(); if(model == "GL"){ cost = 420000; } if (model == "XL"){ cost = 3398000; } System.out.print("Car phone: "); char phone = (char)System.in.read(); if(phone == 'W'){ cost = cost + 40000; } System.out.print("Full or installment: "); char paid = (char)System.in.read(); if(paid == 'F'){ cost = cost - 0.15 * cost; } System.out.print("Cost: " + cost); } } ,那么放置此类字段的正确位置可能是基类之外的其他地方。它可能在某些其他配置对象中。

但即使使用当前的配置,它也没有意义,因为任何修改静态变量的子类都会使变量对所有类都可见。如果子类xB更改为1,则子类x会将其更改为2,新值也会显示为C

我认为你在问题中描述的方式,每个子类都应该有自己独立的静态字段。在抽象基类中,您可以定义每个子类要实现的方法,以便访问每个字段:

B

答案 1 :(得分:1)

正如一些答案和评论已经指出的那样,您的方法不会按照您想要的方式工作,因为每个静态块都会更改所有扩展A的类的静态变量。

请改用接口和实例方法:

public interface A {
    int getX();
}

-

public class B implements A {

    private static final int X = 1;

    @Override
    public int getX() {
        return X;
    }
}

-

A myInstance = new B();
System.out.println(myInstance.getX()); // prints "1"