Java和继承的静态成员

Fr0*_*Bit 16 java inheritance static

假设我有以下课程:

class Parent
{
    private int ID;
    private static int curID = 0;

    Parent()
    {
         ID = curID;
         curID++;
    }
}
Run Code Online (Sandbox Code Playgroud)

和这两个子类:

class Sub1 extends Parent
{
    //...
}
Run Code Online (Sandbox Code Playgroud)

class Sub2 extends Parent
{
    //...
}
Run Code Online (Sandbox Code Playgroud)

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

所以,如果我这样做:

{
    Sub1 r1 = new Sub1(), r2 = new Sub1(), r3 = new Sub1();
    Sub2 t1 = new Sub2(), t2 = new Sub2(), t3 = new Sub2();
}
Run Code Online (Sandbox Code Playgroud)

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

这可能吗?如何?

Lui*_*oza 11

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

  • JLS说了一些不同的东西:http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.8 C类继承了它的直接超类所有具体方法m(两者都是静态和实例)的超类 (3认同)
  • @LuiggiMendoza这是错误的,它们*是*继承的,但*不是*可重写的 (2认同)

And*_*ter 10

正如其他人已经写过的那样,静态成员绑定到类,因此您需要在类级别上跟踪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++;
    }

    //...
}
Run Code Online (Sandbox Code Playgroud)

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

  • 这是一个很好的方法来做OP需要做的事情,但我认为值得一提的是,以这种方式使用静态变量并不是线程安全的.在这里使用单身人士和工厂方法可能是个好主意. (2认同)