子类Java中的静态变量
我需要一个静态变量,它与对象无关,而是与类本身相关。但是,该变量也不得与父类或扩展同一父类的所有其他子类相关 比如说:子类Java中的静态变量,java,oop,object,Java,Oop,Object,我需要一个静态变量,它与对象无关,而是与类本身相关。但是,该变量也不得与父类或扩展同一父类的所有其他子类相关 比如说: class Army{ static int attack = 0; } class Warrior extends Army{ public Warrior(){ attack = 50; // every Warrior object will have attack value of 50
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
}
}
可能吗?或者我需要在每个子类中声明静态变量吗?我尝试过,当我尝试访问静态变量时,每个类的静态变量值都是相同的。不,这是不可能的。
父类对其子类中的静态或非静态成员一无所知
然而,您发布的代码告诉我您想要覆盖一个静态变量。这也是不可能的,只有非静态方法可以被重写(如果它们具有适当的访问级别)。您当前的代码不会执行您想要的操作,因为
陆军
类中只有一个攻击
变量,并且它只能有一个值
您可以在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()
不是一个变量,也不是静态的,它仍然满足您的要求-每个子类都可以有一个由该子类的所有实例共享的不同值。静态变量在类加载器首次加载类时初始化
当您尝试创建say Warrior的实例时,您正在重置攻击变量。因此,在使用Warrior.attack
之前,请执行以下操作:
new Warrior();
System.out.println(Warrior.attack);//output would be 50
我想说的是,您在Army类中创建了一个getAttack方法,并让Warrior和其他人覆盖它。
比如:
class Army{
public int getAttack() {
return 0;
}
}
class Warrior extends Army{
public int getAttack() {
return 50;
}
}
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;
}
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);
}
}
攻击属性不能是静态的,您必须在每个类中定义它。
<强>但请考虑使用EnUM。< /强>
public enum Attack {
Army,
Warrior,
Archer;
}
在一个完美的世界里,你会做如下事情:
class Army{
public int getAttack() {
return 0;
}
}
class Warrior extends Army{
public int getAttack() {
return 50;
}
}
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;
}
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);
}
}
不幸的是,Java不允许这样做
你能得到的最接近的可能是:
class Army{
public int getAttack() {
return 0;
}
}
class Warrior extends Army{
public int getAttack() {
return 50;
}
}
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;
}
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);
}
}
这是不可能做到这一点,你正试图这样做 您想要实现的是,在基类中有一个
静态
变量,然后为其每个子类提供相同变量的不同值
因为它是静态变量,所以所有对象的值都相同。一个子类不能有一个值,另一个子类不能有另一个值。因为它是两个类的一个常见静态变量。因此,它的值对于两个子类都是通用的
您可以在每个子类中使用静态变量,即,
Warrior
拥有自己的静态变量,Archer
拥有自己的静态变量。我假设您的直接问题(静态是否可以继承)已经得到了回答。
我想我应该建议另一种方法:
根据您的问题,我假设您希望避免向每个实例添加4个字节,每个实例具有唯一的attackvalue,因为每个战士有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;
}
}
级陆军{
私有最终ArmyConfiguration配置;
公军(){
这(“军队”);
}
公共军队(字符串配置名称){
this.configuration=ConfigFactory.getInstance().getConfiguration(configurationName)
}
public ArmyConfiguration getArmyConfiguration(){return configuration;}
}
阶级战士{
超级战士;
}
弓箭手{
超级射手;
}
类配置工厂{
私有静态配置工厂实例;
公共同步ConfigFactory getInstance(){
if(实例==null){
实例=新的ConfigFactory();
}
返回实例;
}
私有地图;
公共工厂(){
this.configMap=new HashMap();
configMap.put(“陆军”,新的陆军配置(0));
configMap.put(“战士”,新的兵种配置(50));
configMap.put(“Archer”,新的ArmyConfiguration(75));
}
public ArmyConfiguration getConfiguration(字符串名称){
返回configMap.get(名称);
}
}
类别军备配置{
公共最终int攻击值;
公共ARMY配置(最终int攻击值){
this.attackValue=attackValue;
}
}
当然,这并不理想(单例可能不是您想要的)。此设置允许您从磁盘加载配置,而无需重新编译。(在ConfigFactory构造函数期间,从磁盘加载文件,解析它并构造实例)
通过这种方式,您可以将对象的实际设置/配置与这些对象所需的逻辑分开。对于小规模的东西,硬编码是一种选择,对于较大的项目,您可能希望提取。“每个战士对象的攻击值为50”不正确,静态变量不属于对象静态变量与声明它的类的每个对象共享该值。所以每个子类也会有这个值。如果主类或其他子类更改了该值,则每个类(无论是父类还是子类)都将具有新值。因此,是的,您需要为每个子类声明一个新的静态变量。可能的重复项您需要为每个子类声明一个新的静态变量。为什么这是一个静态变量?对于常量,这将起作用(尽管需要使用int attackValue扩展枚举)。当他试图从外部文件加载这些值时,尽管这会崩溃。