Java и унаследованные статические члены
Предположим, что у меня есть класс ниже:
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();
}
ID r1, r2, r3 будет 0,1,2, а t1, t2, t3 - 3,4,5.
Вместо них я хочу, чтобы t1, t2, t3 имели значения 0,1,2, то есть использовали другую копию статической переменной curID.
Возможно ли это? И как?
Ответы
Ответ 1
Как уже писали другие, статические члены привязаны к классу, поэтому вам нужно отслеживать идентификатор на уровне класса, например. например:
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
static
поля/методы не наследуются. Они относятся к классу, а не к объектным ссылкам.
Ответ 3
Возможно, но не используя один счетчик. Вам понадобится счетчик для каждого подтипа. Например, что-то вроде следующего:
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);
}
Остерегайтесь: приведенное выше не является потокобезопасным. Но ваш исходный код не является...
Ответ 4
Статика - это статика. Существует только один экземпляр curID, период. Поэтому, если вам нужны отдельные счетчики для Sub1 и Sub2, вы объявляете статику в каждом из этих классов.
Ответ 5
Статические элементы вообще не наследуются.
На самом деле нет такой вещи, как Sub1.curID
- это законный (но запутанный) способ обращения к Persion.curID
.
К сожалению, нет никакого способа сделать то, что вам нужно, со статическими ссылками. Они принципиально не работают и не могут работать с присущим им свойством - поскольку они статически разрешены, они не могут полагаться на динамическую отправку и поэтому не могут зависеть от полиморфизма времени выполнения. Учитывая, что JVM/compiler рассматривает статические переменные таким образом, я уверен, что нет обходного пути, которое вы можете придумать, что позволит вам делать то, что вы хотите.
Если идентификаторы действительно должны быть статичными, тогда вам нужно будет определить разные статические переменные в каждом из подклассов.
Ответ 6
В отличие от других ответов, существует решение вашей проблемы, хотя это не связано с "статическим наследованием". У вас должен быть генератор идентификаторов для каждого класса.
Вот хороший пример:
Java: Родительские методы доступа к статическим переменным подкласса?
Ответ 7
Унаследованный статический член не имеет значения!
Статический означает, что он используется всеми экземплярами данного типа.
поскольку Sub1 и Sub2 являются типами Parent,
они имеют одинаковое статическое поле.
Я думаю, что у вас, вероятно, будет проблемный дизайн, если вы чувствуете
вам нужно использовать статическое поле с собственностью.
Просьба описать больше того, что вы пытаетесь достичь.
Ответ 8
статические поля не будут унаследованы. каждый экземпляр будет использовать одно и то же поле. для выполнения того, что вы хотите, я бы изменил поле в поле экземпляра и либо имел один экземпляр, который внутренне увеличивает это поле, либо если вам нужно создать три экземпляра, у вас может быть конструктор, в котором вы передадите добавочное значение.
Ответ 9
Члены static
являются частью объекта Parent.class
в части PermGen
JVM. Все экземпляры этого класса используют одни и те же статические переменные.
Каждый подкласс должен иметь свой собственный static curID
.
Ответ 10
Вы используете переменную static
- Нет копий переменной
static
для разных объектов,
- Будет существовать только копия переменной
static
и она будет использоваться для всех экземпляров
Что касается статического наследования переменных, Они не наследуются вообще
Итак, даже если вы скажете
r1.curID;
t1.curID;
Это будет означать одно и то же, т.е. Parent.curID
Когда вы изменяете переменную static
из экземпляра класса, и если другой экземпляр обращается к этой переменной, он получает измененное значение как свою общую переменную