Мне нужна помощь, дублируя объект в Java

1

Я пишу шахматную игру на Java. У меня есть класс Board, содержащий панель массива String 2D. Мне нужно создать TempBoard, который копирует mainBoard. Внесите некоторые изменения и выполните тесты на tempBoard без изменения массива 2d в mainBoard.

public class Board implements Cloneable {

public String[][] board = new String[][]{
    {"bR ", "bN ", "bB ", "bQ ", "bK ", "bB ", "bN ", "bR "},
    {"bp ", "bp ", "bp ", "bp ", "bp ", "bp ", "bp ", "bp "},
    {"   ", "## ", "   ", "## ", "   ", "## ", "   ", "## "},
    {"## ", "   ", "## ", "   ", "## ", "   ", "## ", "   "},
    {"   ", "## ", "   ", "## ", "   ", "## ", "   ", "## "},
    {"## ", "   ", "## ", "   ", "## ", "   ", "## ", "   "},
    {"wp ", "wp ", "wp ", "wp ", "wp ", "wp ", "wp ", "wp "},
    {"wR ", "wN ", "wB ", "wQ ", "wK ", "wB ", "wN ", "wR "}
};


public Board() {

}

@Override
public Object clone() throws CloneNotSupportedException {
    return super.clone();
}

}

Board tempBoard = (Board ) Mainboard.clone();
                    tempBoard.updateBoard(move);

^ в другом классе в основном Я пытаюсь обновитьBoard на tempBoard, но это также изменяет массив в mainBoard. Какие-либо предложения?

Теги:
oop

4 ответа

2

Java clone() затруднительно. Попробуйте создать конструктор копирования.

public static Board newInstance(Board board)
{
    // Set fields as appropriate to your Board class
    return new Board(board.getFoo(), board.getBar());
}
1

Ваш клонированный объект ссылается на один и тот же массив массивов. Возможное решение:

@Override
public Object clone() throws CloneNotSupportedException {
    Board b = new Board();
    b.board = (String[][]) this.board.clone();
    return b;
}
  • 0
    clone должен вызывать родительский метод clone (), а не конструктор, см. stackoverflow.com/questions/1052340/…
  • 0
    @SteveKuo public Object clone() { Board clone = (Board).super.clone(); return clone; } это выдает ошибку под (Board)
0

Первая проблема здесь заключается в том, что ваша реализация cloneable - это просто вызов метода родительского класса. Родительский класс понятия не имеет о вашем board поэтому он не может клонировать это. Причина, по которой это исключение не вызывает, заключается в том, что вы все еще получаете ссылку на свойство доски, когда вы возвращаете MainBoard.clone() в Board. Фактически вы должны реализовать метод clone и вернуть копию текущего экземпляра.

Вы также должны избегать придания объектов. Есть несколько ситуаций, когда литье необходимо и имеет смысл, но в большинстве случаев это помогает путанице в отношении типа объекта.

Надеюсь, я помог.

0

"clone" - это минное поле в Java. Я рекомендую не использовать интерфейс Cloneable или сделать метод clone. Поиск по "Java clone", вероятно, даст вам много информации об этом.

  • Я бы рекомендовал метод copy().
  • Обычно копирование означает создание копии, которая отделена от оригинала, и это то, что вы хотите сделать. Это попадает в изменчивые и неизменные объекты. Вы хотите неизменный объект, что означает, что он не может быть изменен. Обычно это означает, что любые поля являются частными, и для полей нет методов setter. Усложнение возникает, когда объект состоит из других объектов. Вы можете сделать объект верхнего уровня неизменным, но если объекты внутри изменяемы, и эти объекты могут быть доступны в другом месте, то верхний объект не является действительно неизменным.

Вот пример:

public class Widget {
    public int number = 0;
    public String name = "";
}

public class BunchOfWidgets {
    private List<Widget> bunch;
    public BunchOfWidgets(List<Widgets> widgetsIn) {
        bunch = widgetsIn;
    }
    public String getName(int i) {
       return bunch.get(i).name;
    }
}

Затем в другом месте вы создаете кучу виджетов:

List<Widgets> listOfMutableWidgets = getMutableWidgetList();
BunchOfWidgets immutableBunch = new BunchOfWidgets(listOfMutableWidgets);
listOfMutableWidgets.get(0).number = 1;
listOfMutableWidgets.get(0).name = "Metamorph";

Теперь immutableBunch неизменен, но вы изменили поле имени первого элемента в этом личном списке. Список является закрытым, но элементов нет.

Поэтому вы должны быть осторожны, чтобы объекты были неизменными на всех уровнях. Это означает, что поля должны быть частными, чтобы методы возвращали копии значений полей, а если у конструкторов есть аргументы Object, которые задают частные поля, аргументы копируются по полю (рекурсивно вниз, если необходимо) в частные поля в вашем классе. Копирование примитивных типов безопасно, поскольку они не являются объектами, а скорее значениями. Строка неизменна, но то, что String находится в заданном индексе в массиве, или Collection не является, если вы не сделаете массив или коллекцию неизменяемыми. То же самое верно для удаления строк. Такая же логика применяется к любому неизменяемому объекту в изменяемом массиве или коллекции.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню