Может ли объект управляться несколькими классами? (и как это остановить)

1

У меня есть объект Point, который содержит координаты, затем я использую эту Точку в создании двух других объектов: треугольника и круга, а затем внутри объекта круга, который я перевожу эту точку. Он также переводит точку в классе треугольника. Почему это? Я просто создал две переменные для доступа к одному и тому же объекту, а не к "копии" этого объекта в обеих фигурах? Как я могу это изменить?

Я создаю точку в основном классе, затем передаю эту точку на конструкторы классов Circle и Triangle, которые затем присваивают ей свойство этого класса.

Так вот так:

//main class
Point p = new Point(50,50);
Circle c = new Circle(p);
Triangle t = new Triangle(p);

c.translate(20,30); //also translates the triangles point

//Circle class
public Circle(Point p) {
    this.p = p;
}


//Triangle class
public Triangle(Point p) {
    this.p = p;
}
  • 0
    и какая именно у вас проблема с этим?
  • 0
    Пока ваша Точка неизменна, я думаю, что на самом деле это хорошая идея, что одна и та же Точка совместно используется всеми классами в максимально возможной степени. Это хорошая экономия памяти.
Теги:
class
object

3 ответа

1
Лучший ответ

Да, вы передали две ссылки на тот же объект Point на Circle и Triangle.

Чтобы этого избежать, в основном существуют два решения:

  • создайте копию объекта Point (либо перед передачей ее в Triangle и Circle, либо в конструкторе этих двух классов, чтобы убедиться, что они используют разные экземпляры)
  • сделайте класс Point неизменным (все поля final, no setter), чтобы никто не мог изменить точку. Чтобы перевести точку, вы должны были бы создать новую Точку с новыми координатами. Это намного безопаснее, потому что вы не можете забыть сделать копию. Неизбежность гарантирует, что точка может быть разделена между фигурами без какого-либо способа изменить их, изменив их точки.
  • 0
    Спасибо, мне придется скопировать объект, я следую строгой спецификации>.>
1

Конструкторы для обоих классов Circle и Triangle просто назначают Point они передают члену данных. Таким образом, вы сохраняете ссылку на один и тот же объект, и каждый раз, когда он обрабатывается, он будет обрабатывать все ссылки на него.

Более безопасный способ обработки таких ситуаций - это, как вы предположили, копировать объект, переданный конструктору. Например:

//Circle class
public Circle(Point p) {
    this.p = new Point(p.getX(), p.getY());
}

В качестве альтернативы, если вы определили Point как clonable:

//Circle class
public Circle(Point p) {
    this.p = p.clone();
}
  • 0
    Спасибо, я слышал, что следует избегать клонирования объектов?
  • 0
    clone() имеет странную семантику, правда. Лично я стараюсь этого избегать, но некоторые фреймворки / проекты используют это. Я думаю, это вопрос стиля.
0

Вы создаете один экземпляр объекта Point и ссылаетесь на этот объект Point в экземплярах объекта Circle и Triangle. Метод translate модифицирует объект Point.

Ещё вопросы

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