Как вы создаете экземпляр класса, который вызывает другой экземпляр самого себя? - PullRequest
4 голосов
/ 16 апреля 2020

Я пытаюсь закодировать кубик Рубика и хочу иметь шесть классов Лица для каждого лица куба. В классе мне нужен доступ к граням по всем четырем сторонам, чтобы правильно перемещать куб, поэтому я попытался добавить четыре других объекта Face в конструктор Face. Мне интересно, сработает ли этот экземпляр. Вот как я это сделал (первый кусок кода находится в основном классе, а второй - из класса Face):

white = new Face(red, blue, green, orange, Color.WHITE);
yellow = new Face(orange, blue, green, red, Color.YELLOW);
red = new Face(yellow, blue, green, white, Color.RED);
orange = new Face(white, blue, green, yellow, Color.ORANGE);
blue = new Face(red, yellow, white, orange, Color.BLUE);
green = new Face(red, white, yellow, orange, Color.GREEN);
front = yellow;



public Face top, left, right, bottom;
public Cell[][] cells;

public Face(Face t, Face l, Face r, Face b, Color c) {
    top = t;
    left = l;
    right = r;
    bottom = b;
    cells = new Cell[3][3];
    for(int row = 0; row < 3; row++) {
        for(int col = 0; col < 3; col++) {
            cells[row][col] = new Cell(c);
        }
    }
}

Ответы [ 3 ]

2 голосов
/ 16 апреля 2020

Вы можете инициализировать Face без соседних граней. Затем, после того как все они инициализированы, вы определяете отношения между ними с помощью сеттеров.

class Face {
  Face white = new Face(Color.WHITE);
  Face yellow = new Face(Color.YELLOW);

  {
    white.setRight(yellow);
    yellow.setLeft(white);
  }


  public Face top, left, right, bottom;
  public Cell[][] cells;

  public Face(Color c) {
    // only cells init
  }

  public void setLeft(Face left) {
    this.left = left;
  }

  public void setRight(Face right) {
    this.right = right;
  }

}
1 голос
/ 16 апреля 2020

Что я обычно делаю, это добавляю функцию инициализации, которая используется после того, как все объекты созданы, и перемещаю код, которому нужны другие экземпляры. Таким образом, у вас уже есть действительные ссылки, когда ваш код называется:

    // Instantiate the objects:
    white = new Face(Color.WHITE);
    yellow = new Face(Color.YELLOW);
    red = new Face(Color.RED);
    orange = new Face(Color.ORANGE);
    blue = new Face(Color.BLUE);
    green = new Face(Color.GREEN);
    // Initialize the objects:
    white.intitializeFace(red, blue, green, orange);
    yellow.intitializeFace(orange, blue, green, red);
    red.intitializeFace(yellow, blue, green, white);
    orange.intitializeFace(white, blue, green, yellow);
    blue.intitializeFace(red, yellow, white, orange);
    green.intitializeFace(red, white, yellow, orange);

    front = yellow;

    public Face(Color c) {
        cells = new Cell[3][3];
        for(int row = 0; row < 3; row++) {
            for(int col = 0; col < 3; col++) {
                cells[row][col] = new Cell(c);
            }
        }
    }
    public void intitializeFace(Face t, Face l, Face r, Face b) {
        top = t;
        left = l;
        right = r;
        bottom = b;
    }
0 голосов
/ 16 апреля 2020

Этот пример не будет работать, потому что вы не можете ссылаться на объекты до того, как они будут созданы, если они не были объявлены с некоторым состоянием.

При этом, если у вас есть другой объект, скажем, Блок, который содержит объект с четырьмя лицами, это решит вашу проблему. Лицо может состоять только из Цвета, а Блок может управлять всеми логинами c.

enum Face {
    WHITE(Color.WHITE),
    RED(Color.RED),
    BLUE(Color.BLUE)
    // other elements
    // constructor
    // getters
}
class Block {

    // class members

    // cells

    public Block(Face top, Face left, Face right, Face bottom) {
        // assignment
    }

}
...