Я попытался максимально упростить, чтобы не спамить вас со стеной кода из моей игры
Скажем, у меня есть объект класса XY, который содержит ArrayList объектов Z. Как я могу адресовать член (int number) объекта XY из метода внутри класса Z.
class XY {
static int nextID = 0;
final int id;
int number;
List<Z> zList = new ArrayList<Z>();
XY(int number) {
this.id = nextID++;
this.number = number;
zList.add(new Z(id));
}
..
class Z {
final int id;
Z (int id) {
this.id = id;
}
void getXYNumber() {
int n = // ?
}
}
Я мог найти только обходное решение, потому что в моем случае класс XY также просто хранится как массив в классе, вызывающем его теперь ABC, и все объекты Z имеют тот же идентификатор, что и класс XY, который содержит объекты Z, поэтому я могу использовать это id, чтобы идентифицировать объект XY внутри ABC из метода getXYid внутри Z, я звоню.
class ABC {
static XY[] = new XY[]{12, 45, 86};
static XY getXY(int id) {
for(XY xy: xyList) {
if (xy.id = id) return xy;
}
}
}
class Z {
void getXYid() {
int n = ABC.getXY().number;
}
}
Есть ли какое-либо ключевое слово или что-то, чтобы получить конкретный XY, который удерживает Z с помощью метода, который я вызываю, или это уже лучшее решение?
Примечание. В этом случае член для определения класса является идентификатором int, который может быть просто использован как индекс из массива XY внутри класса ABC, но в моем случае объект для идентификации класса представляет собой перечисление, называемое Owner, которое является всем то же самое для всех объектов Z внутри объекта XY, так что это не сработает.
Создайте поле типа XY
в Z
и задайте его при создании Z
Это также устранит необходимость копирования поля id
.
class XY {
static int nextID = 0;
int id;
int number;
List<Z> zList = new ArrayList<Z>();
XY(int number) {
this.id = nextID++;
this.number = number;
zList.add(new Z(this));
}
class Z {
XY xy;
Z (XY xy) {
this.xy = xy;
}
int getXYId() {
return xy.id;
}
int getXYNumber() {
return xy.number;
}
}
Этот тип циркулярной ссылки обычно считается плохой практикой и во многих случаях указывает на необходимость пересмотра архитектуры приложения/дизайна.
Я считаю, что есть два простых решения. Если значение number
в XY
не изменяется, я бы предложил передать number
конструктору Z
как:
class Z {
int xyNumber
final int id;
Z (int id, int xyNumber) {
this.id = id;
this.xyNumber = xyNumber;
}
void getXYNumber() {
int i = // ?
}
}
В приведенном выше примере вы можете вызвать свой конструктор следующим образом: new Z(id, number);
Если значение числа изменится, вы можете передать фактический объект XY
в конструктор Z
Этот объект является ссылкой, поэтому, если исходные изменения, версия внутри объекта Z
также изменяется. Это дает вам самое последний number
значение. Когда объект Z
передается другому XY
, вы можете обновить currentXY
используя void setXY(XY)
class Z {
final int id;
XY currentXY;
Z (int id, XY currentXY) {
this.id = id;
this.currentXY = currentXY;
}
void getXYNumber() {
int i = // ?
}
void setXY(newXY) {
currentXY = newXY;
}
}
В приведенном выше примере вы можете вызвать свой конструктор следующим образом: new Z(id, this);
, они ключевое слово, this
даст вам текущий объект, с которым вы работаете, что в вашем случае является XY
объектом.
class Z { private final XY xy; public X(XY xy) { this.xy = xy; } }
)