我需要一个与对象无关的静态变量,而是与类本身有关。但是,该变量也必须与父类或扩展相同父类的所有其他子类无关。
让我们说:
class Army{
static int attack = 0;
}
class Warrior extends Army{
public Warrior(){
attack = 50; // every Warrior object will have attack value of 50
}
}
class Archer extends Army{
public Archer(){
attack = 75; // every Archer object will have attack value of 75
}
}
有可能吗?或者我是否需要在每个子类中声明静态变量?我试过,当我试图访问静态变量时,静态变量的值对于每个类都是相同的。
答案 0 :(得分:5)
您当前的代码将无法执行您想要的操作,因为attack
类中只有一个Army
变量,并且它只能有一个值。
您可以在Army中使用返回默认值的方法:
public int getAttack()
{
return 10;
}
然后你可以在子类中覆盖这个方法:
class Warrior extends Army
{
...
@Override
public int getAttack()
{
return 50;
}
...
}
class Archer extends Army
{
...
@Override
public int getAttack()
{
return 75;
}
...
}
即使getAttack()
不是变量,并且它不是静态的,它仍然满足您的要求 - 每个子类可以具有该子类的所有实例共享的不同值。
答案 1 :(得分:2)
不,不可能。 父类对其子类中的静态或非静态成员一无所知。
但是,您发布的代码告诉我要覆盖静态变量。这也是不可能的,只能覆盖非静态方法(如果它们具有适当的访问级别)。
答案 2 :(得分:1)
攻击属性不能是静态的,您必须在每个类中定义它 但请考虑使用枚举。
public enum Attack {
Army,
Warrior,
Archer;
}
public class Army {
private final Attack attack = Attack.Army;
}
public class Warrior extends Army{
private final Attack attack = Attack.Warrior;
}
public class Archer extends Army{
private final Attack attack = Attack.Archer;
}
答案 3 :(得分:0)
当类首次由类加载器加载时,静态变量被初始化。
当您尝试创建说Warrior的实例时,您正在重置攻击变量。因此,在使用Warrior.attack
之前,请执行以下操作:
new Warrior();
System.out.println(Warrior.attack);//output would be 50
我会说你在陆军类中创建一个getAttack方法,然后让Warrior和其他方法覆盖它。 类似的东西:
class Army{
public int getAttack() {
return 0;
}
}
class Warrior extends Army{
public int getAttack() {
return 50;
}
}
答案 4 :(得分:0)
在一个完美的世界中,你会做类似的事情:
abstract class Army {
// Final to make sure it is filled in - abstract to postpoone that to sub-classes.
// NB: NOT valid Java.
abstract final int attack;
}
不幸的是,Java不允许这样做。
你能得到的最接近的东西是:
class Army {
// Final to make sure it is filled in.
final int attack;
// Forces subclassses to use super(attack).
public Army(int attack) {
this.attack = attack;
}
}
class Warrior extends Army {
public Warrior() {
// I get an error if I don't do this.
super(50);
}
}
答案 5 :(得分:0)
不可能按照你想要的方式这样做。
你想要实现的是,在基类中有一个static
变量,然后为每个子类赋予相同变量的不同值。
因为它是静态变量,所以它对所有对象都具有相同的值。它不能为一个子类提供一个值,为其他子类提供其他值。因为它是两个类的一个常见静态变量。因此,无论它的价值如何,对于两个子类都是常见的。
你可以做的是在每个子类中都有静态变量,即Warrior
有自己的静态变量,Archer
有自己的静态变量。
答案 6 :(得分:0)
我假设你的直接问题(可以静态继承)已被回答。 我以为我建议采用另一种方法:
从你的问题我假设你想避免为每个实例添加4个字节及其独特的攻击值,因为每个战士有50次攻击,它应该是列出这个的1个地方。 对于1个数字,此解决方案仍将花费4个字节,但如果超过1个这样的数字,则会更优化。
class Army {
private final ArmyConfiguration configuration;
public Army() {
this("Army");
}
public Army(String configurationName) {
this.configuration = ConfigFactory.getInstance().getConfiguration(configurationName)
}
public ArmyConfiguration getArmyConfiguration() { return configuration; }
}
class Warrior {
super("Warrior");
}
class Archer {
super("Archer");
}
class ConfigFactory {
private static ConfigFactory instance;
public synchronized ConfigFactory getInstance() {
if (instance == null) {
instance = new ConfigFactory();
}
return instance;
}
private Map<Class, ArmyConfiguration> configMap;
public ConfigFactory() {
this.configMap = new HashMap<Class, ArmyConfiguration>();
configMap.put("Army", new ArmyConfiguration(0));
configMap.put("Warrior", new ArmyConfiguration(50));
configMap.put("Archer", new ArmyConfiguration(75));
}
public ArmyConfiguration getConfiguration(String name) {
return configMap.get(name);
}
}
class ArmyConfiguration {
public final int attackValue;
public ArmyConfiguration(final int attackValue) {
this.attackValue = attackValue;
}
}
当然,这并不理想(单身可能不是你想要的)。此设置将允许您从磁盘加载配置,而无需重新编译。 (在ConfigFactory构造函数中,从磁盘加载文件,解析它并构造实例)
这样,您可以将对象的实际设置/配置与这些对象所需的逻辑分开。对于小规模的东西,硬编码是一种选择,对于您可能想要提取的大型项目。