【问题标题】:How can my subclass properly inherit a static variable我的子类如何正确继承静态变量
【发布时间】:2014-04-23 00:52:00
【问题描述】:
public abstract class SuperClass {
    public int x, y;
    public static int z;
}

我希望 SuperClass 的每个子类都有静态变量 z。自然地,z 将包含每个子类的不同值。我希望避免在每个子类中定义 z,因为它将成为值 x 和 y 的函数依赖;这可能吗?

【问题讨论】:

  • 不,static 变量属于声明它们的类。你能做的最好的就是隐藏它们。
  • "自然地,z 将包含每个子类的不同值" => 不,它不会...
  • @assylias 对不起。自然应该..

标签: java inheritance static superclass


【解决方案1】:

如果我理解正确,那就做

public abstract class SuperClass {

  public int x, y, z;
  public SuperClass(int z) {

    this.z = z;

  }

}   

那么任何扩展这个类的类都会继承z;

【讨论】:

  • 甚至可能是 z 的 getter 和 setter。
【解决方案2】:

与“每个实例一个”的实例变量不同,static 变量不是“每个子类一个”——它们是“每个声明类一个”。换句话说,SuperClass 的子类共享 SuperClass.z,但它们不能逐个类地“覆盖”它。

这并不意味着您不能自己实现它:在创建自己的整数的每个子类存储的方法是在SuperClass 中添加一个static Map<Class,int> zs,并带有用于访问数据的可选函数:

public abstract class SuperClass {
    public int x, y;
    private static Map<Class,Integer> zs = new HashMap<Class,Integer>();
    protected static int getZ(Class c) {
        Integer res = zs.get(c);
        return res == null ? -1 : res.intValue();
    }
    protected static void setZ(Class c, int v) {
        zs.put(c, v);
    }
}
class SubClassOne extends SuperClass {
    public int getZ() {
        return SuperClass.getZ(SubClassOne.class);
    }
}
class SubClassTwo extends SuperClass {
    public int getZ() {
        return SuperClass.getZ(SubClassTwo.class);
    }
}

【讨论】:

  • 或者我可以将public static int z = x 放在每个子类中。无论我想要多少个子类,它都不会产生比您的建议更多的代码行,对吧?
  • @user2651804 这是正确的。唯一的区别是超类无法轻松访问zs 的每个子类存储库。
  • 就我而言,我不需要这个。我一直计划通过引用 SubclassA.z、SubclassB.z 等从外部类访问 z 值。我可能有一些可怕的设计缺陷:P
【解决方案3】:

可能最好的方法是在抽象类中使用z() 方法或类似方法,并在所需的子类中覆盖该方法。

例子:

public abstract class SuperClass {
  public int x, y;

  protected int z() {
     return 42; // protected so only subclasses can see it - change if required
  }
}


public class SubClassOne extends SuperClass {

  public void foo() {
    // do something...
    int z = z();
    // something else...
  }
}

public class SubClassTwo extends SuperClass {

  @Override
  protected int z() {
    return 1;
  }

  // use z() accordingly
}

【讨论】:

  • 我认为这是提问者想要的。我会将公共静态字段添加到类中,这样我就不需要需要 有一个实例来检索该字段。实际使用中的一个例子是 Antlr:Lexerpublic abstract String[] getTokenNames();,子类有 public static final String[] tokenNames = {...}; 并实现该方法。
  • @SillyFreak 好吧,他的 SubClassTwo 所做的正是我想要实现的——只是以一种更聪明的方式,这似乎是不可能的。它也比不上public static z = 1,那为什么还要编写不必要的代码呢?
  • 这两者在动态绑定方面有一个非常重要的区别。考虑两个实例SuperClass sup; SubClass sub;,以及一个访问z 的非静态方法SuperClass.foo()SuperClassSubClass 都声明 static int z;sup.foo();sub.foo(); 都将使用 SuperClass.z,因为静态绑定。您可能期望的行为是访问的 z 取决于对象的身份,而不是声明 foo() 的类。如果那是您想要的,那么您很好,但是非常很好地记录该决定;它可能会让其他开发者感到困惑。
  • 愚蠢的怪胎 - 这是一个很好的观点。由于测试原因,我一般不喜欢静态,但在这种情况下,它可能是合理的。
猜你喜欢
  • 2013-07-12
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 2011-08-05
  • 2017-02-07
  • 2019-04-28
  • 1970-01-01
  • 2012-02-18
相关资源
最近更新 更多