Это неизменный класс? - PullRequest
       10

Это неизменный класс?

12 голосов
/ 30 сентября 2010

Я понятия не имею, как должен выглядеть неизменный класс, но я уверен, что это тот класс Я прав? Если нет, укажите, что следует добавить / удалить.

import java.io.Serializable;

public class Triangle implements IShape, Serializable {
    private static final long serialVersionUID = 0x100;

    private Point[] points;

    public Triangle(Point a, Point b, Point c) {
        this.points = new Point[]{a, b, c};
    }

    @Override
    public Point[] getPoints() {
        return this.points;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) return false;
        if (this == obj) return true;
        if (getClass() != obj.getClass()) return false;
        Point[] trianglePoints = ((Triangle) obj).getPoints();
        for (int i = 0; i < points.length; i++){
            if (!points[i].equals(trianglePoints[i])) return false;
        }
        return true;
    }
}

Это поможет?

@Override
    public Point[] getPoints() {
        Point[] copyPoint = {
                new Point(points[0]),
                new Point(points[1]),
                new Point(points[2]),};
        return copyPoint;
    }

Класс очков:

import java.io.Serializable;

public class Point implements Serializable {
    private static final long serialVersionUID = 0x100;

    public int x;
    public int y;
    public int z;

    public Point(int x, int y, int z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public Point(Point that) {
        this.x = that.x;
        this.y = that.y;
        this.z = that.z;
    }

    public boolean equals(Object obj) { 
        // assume this is a typical, safe .equals implementation
        // that compares the coordinates in this instance to the
        // other instance
        return true;
    }
}

Ответы [ 14 ]

0 голосов
/ 30 сентября 2010

Это может быть лучше Point реализация. import java.io.Serializable;

public final class Point implements Serializable {
    private static final long serialVersionUID = 0x100;

    private final int x;
    private final int y;
    private final int z;

    public Point(int x, int y, int z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public Point(Point that) {
        this(that.x, that.y, that.z );
    }

    public boolean equals(Object obj) { 
        // assume this is a typical, safe .equals implementation
        // that compares the coordinates in this instance to the
        // other instance
        return true;
    }
}
0 голосов
/ 30 сентября 2010

1) Сделайте участников приватными и финальными - так что

private Point[] points; //should be 
private final Point[] points;

2) Завершить класс, чтобы его нельзя было разделить на подклассы

3) Исключительный доступ к изменяемым элементам (массиву) - означает возвращаемую копию, а не ссылку на изменяемые элементы

Для лучшего рассмотрения этого предмета обратитесь к Joshua Bloch, Effective Java-item 15

0 голосов
/ 30 сентября 2010

В дополнение к тому, что уже отметили другие, вы должны:

  • Создайте свой класс треугольников final, чтобы предотвратить создание изменяемых треугольников подклассами.
  • Объявите все поля окончательными, чтобы отловить случайное изменение полей самим классом.

В «Эффективная Java» Джошуа Блох предоставляет список правил для неизменяемых классов в целом в Элемент 15: Минимизируйте изменчивость.

0 голосов
/ 30 сентября 2010

Это не является неизменным, потому что ...

Triangle t1 = new Triangle(new Point(0,0), new Point(0, 10), new Point(10, 10));
Triangle t2 = t1;

System.out.println( t1.getPoints()[0] );  // -> 0

t2.getPoints()[0].x = 10;

System.out.println( t1.getPoints()[0] );  // -> 10

Таким образом, класс не является неизменным, потому что вы можете изменить состояние экземпляра (внутренний Point[] выставлен) и этотакже изменяет состояние ссылки на тот же экземпляр.

Чтобы сделать его истинным неизменяемым классом, вам потребуются методы для раздельного получения X и Y из каждой точки, например:

public int getPointX(int point) { return points[point].x; }
public int getPointY(int point) { return points[point].y; }

или

public Point getPoint(int point) { return new Point(points[point]); }

или верните копию points, как вы предлагали при редактировании.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...