Java和inheritance的静态成员

假设我有以下课程:

class Parent { private int ID; private static int curID = 0; Parent() { ID = curID; curID++; } } 

和这两个子类:

 class Sub1 extends Parent { //... } 

 class Sub2 extends Parent { //... } 

我的问题是这两个子类从父类共享相同的静态curID成员,而不是具有不同的子类。

所以,如果我这样做:

 { Sub1 r1 = new Sub1(), r2 = new Sub1(), r3 = new Sub1(); Sub2 t1 = new Sub2(), t2 = new Sub2(), t3 = new Sub2(); } 

r1,r2,r3的ID为0,1,2,t1,t2,t3的ID为3,4,5。 而不是这些我希望t1,t2,t3具有值0,1,2,即使用curID静态变量的另一个副本。

这可能吗? 如何?

正如其他人已经写过的那样,静态成员绑定到类,因此您需要在类级别上跟踪id,例如:

 abstract class Parent { private int ID; Parent() { ID = nextId(); } abstract protected int nextId(); } class Sub1 extends Parent { private static int curID = 0; protected int nextId() { return curID++; } //... } class Sub2 extends Parent { private static int curID = 0; protected int nextId() { return curID++; } //... } 

请注意,这种方法不是线程安全的 – 但问题中的代码也不是。 您不能从不同的线程同时从同一子类创建新对象。

虽然static字段/方法是inheritance的,但它们不能被覆盖,因为它们属于声明它们的类,而不是对象引用。 如果你试图覆盖其中一个,你将要做的就是隐藏它。

这是可能的,但不能使用单个计数器。 每个子类型都需要一个计数器。 例如,类似于以下内容:

 private static Map, Integer> counters = new HashMap<>(); Parent() { Integer curID = counters.get(this.getClass()); if (curID == null) { curID = 0; } ID = curID; curID++; counters.put(this.getClass(), curID); } 

注意:以上内容不是线程安全的。 但是你的初始代码不是……

静力学是静力学的静力学。 只有一个curID实例,句号。 因此,如果您想要Sub1和Sub2的单独计数器,则在每个类中声明静态。

与其他答案所说的不同,有一个问题的解决方案,尽管它不涉及“静态inheritance”。 你应该有一个每类ID生成器。

这是一个很好的例子:

Java:父方法访问子类的静态变量?

静态元素根本不会被inheritance。

实际上没有Sub1.curID这样的东西 – 这是一种引用Persion.curID的合法(但令人困惑)的方式。

不幸的是,没有任何方法可以使用静态引用来完成您所需的操作。 它们基本上没有也不能用于固有 – 因为它们是静态解析的,它们不能依赖于动态调度,因此不能依赖于运行时多态性。 鉴于JVM /编译器以这种方式处理静态变量,我相信没有可用的解决方法可以让你做你想做的事情。

如果ID确实需要是静态的,那么您需要在每个子类中定义不同的静态变量。

static成员是JVM的PermGen部分中Parent.class对象的一部分。 该类的所有实例共享相同的静态变量。

每个子类都应该有自己的static curID

静态字段不会被inheritance。 每个实例都将使用相同的字段。 要完成你想要的东西我会将字段更改为一个实例字段,并且有一个实例在内部递增此字段,或者如果您需要创建三个实例,您可以使用构造函数来传递递增的值。

您正在使用static变量

  • 对于不同的对象,没有static变量的副本,
  • 将只有static变量的副本,它将被共享给所有实例

关于静态变量inheritance, 它们根本不是inheritance的

所以,即使你说

 r1.curID; t1.curID; 

这意味着同样的事情,即Parent.curID

当您从类的实例更改static变量时,如果另一个实例正在访问该变量,它将获得更改的值作为其共享变量