2011-10-21 78 views
1

是否可以让给定的子类在其超类中初始化静态最终字段?本质上,我希望子类能够配置所需的全班变量。不幸的是,抽象关键字并不完全适用于字段..java中的最终字段继承

+1

static fields ???遗产??? –

+0

我想我只是想通过要求子类声明给定的字段来避免代码重复。这些变量不会与每个实例一起分配,因为在这种情况下这是没有意义的(maxHealth,maxEnergy等) – lowq

回答

5

不 - 你会如何期待它的工作,如果有两个子类试图做同样的事情?如果你有静态final字段,它们必须由声明它们的类来初始化。

如果你正在尝试使用静态字段和继承在一起,这就是通常一个标志,什么是错的与开始,说实话 - 他们是两个概念,它一般不玩好起来。人们经常试图用静态方法来“伪造”继承,并且通常会严重结束 - 这听起来像是该主题的变体。

如果您可以描述您的更广泛的图片,我们可能会帮助您更多。顺便提一下,为了可测试性,我会敦促您避免使用静态的一般的。它们适用于真正的常量,但如果它与配置类似,则在构建对象(IMO)时传递相关设置会更好。

编辑:我可以看到这将您的情况更好的模型四个选项:

  1. 使用注释:看到真正的软的答案
  2. maxHealth一个方法,所以你可以问任何球员什么他们的最大健康 - 这是再多态性,所以可以在每个类中重写
  3. 型号PlayerPlayerClass分开:

    public class Player { 
        private final PlayerClass playerClass; 
        private int health; // etc 
    } 
    
    public class PlayerClass { 
        private final int maxHealth; //etc 
    } 
    

    这样,你可以在“玩家级”水平的继承,但是你没有 - 你可以创建几个PlayerClass情况下,其行为同样的方式,但有不同的统计...或者您可以继承PlayerClass以提供自定义行为。在这一点上,你可能根本不需要Player的不同子类。

  4. 同为3的想法,但使用的枚举:

    public enum PlayerClass { 
        ELF(10), DWARF(9), HUMAN(5); 
    
        private final int maxHealth; 
        private PlayerClass(int maxHealth) { 
         this.maxHealth = maxHealth; 
        } 
    } 
    

个人我的偏好将是最后的选择,我怀疑。你可以仍然重写行为,但你有一组固定的可能类 - 这可能会合理准确地模拟你的游戏。

+0

>否 - 如果有两个试图做同样事情的子类,那么您会如何工作?如果 >你有静态的最终字段,它们必须是 由声明它们的类初始化。“ Ahhh当然。基本上我想要做的是在我正在工作的游戏上实现一个类系统(速度,健康等) – lowq

+0

@ user984799:听起来不像是应该使用静态字段... –

+0

但是我没有感觉每个班的实例都应该每次分配maxHealth,maxEnergy等。 – lowq

1

关于Jon Skeet的回答,我认为它不是那么糟糕“如果你试图一起使用静态字段和继承”。我建议你使用注释:

@Inherited 
@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.TYPE) 
@interface AValue { 
    /** 
    * @return something final that is "static" (attached to a class), 
    * but also "abstract" (looks that it be changed in the subclasses) 
    */ 
    String value(); 
} 

@AValue("A default value") // you can ommit this, but all subclasses should add the annotation (so the method from Utils work OK) 
abstract class A { } 

@AValue("Value for class B") 
class B extends A { } 

@AValue("Value for class C") 
class C extends A { } 

class Utils { 
    static String getValueOfClass(Class<? extends A> clazz) { 
     return clazz.getAnnotation(AValue.class).value(); 
    } 
} 
+0

所以你已经提出了一些*不是静态字段......这很好,但是以什么方式违背我的建议不使用静态字段? –

+0

它不是静态的,但它的行为像一个静态字段(值是一个类,而不是一个实例) –

+0

我不会认为这是因为试图使用静态字段和继承 - 当然不是那样OP是。我仍然认为将“玩家”数据与“玩家类”数据分开是比较好的,说实话。不需要反思,没有机会宣布注解等。 –