Java和继承的静态成员

时间:2013-06-18 14:50:38

标签: java inheritance static

假设我有以下课程:

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静态变量副本。

这可能吗?如何?

9 个答案:

答案 0 :(得分:10)

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

答案 1 :(得分: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++;
    }

    //...
}

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

答案 2 :(得分:2)

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

private static Map<Class<?>, Integer> counters = new HashMap<>();

Parent() {
     Integer curID = counters.get(this.getClass());
     if (curID == null) {
         curID = 0;
     }
     ID = curID;
     curID++;
     counters.put(this.getClass(), curID);
}

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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

与其他答案不同的是,虽然它不涉及“静态继承”,但您的问题有一个解决方案。你应该有一个每类ID生成器。

这是一个很好的例子:

Java: Parent Methods accessing Subclasses' static variables?

答案 5 :(得分:0)

根本不会继承静态元素。

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

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

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

答案 6 :(得分:0)

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

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

答案 7 :(得分:-1)

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

答案 8 :(得分:-1)

您使用的是static变量

  • 不同对象的static变量没有副本,
  • 只有static变量的副本,并且将为所有实例共享

关于静态变量继承,它们根本不会继承

所以即使你说

r1.curID;
t1.curID;

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

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