Конструктор, который может сделать копию или ссылку - PullRequest
1 голос
/ 09 ноября 2011

Код ниже показывает класс прямоугольника с использованием double точек, которые также хранятся в объекте. Прямоугольник и точки в прямоугольнике являются неизменными, потому что их не нужно менять. Я хотел бы предоставить возможность копировать (создавать новые точечные объекты) или ссылаться на точки, предоставленные в конструкторе, но единственный способ, которым я мог бы подумать, это добавить логический параметр, указывающий, хочет ли вызывающий сделать копия или ссылка.

Это для расширяемости, хотя это может и не иметь первостепенного значения, я бы хотел эту опцию. Однако мне не нравится, как это реализовано с помощью логического параметра. Есть ли способ, которым я могу сделать два конструктора, принимающих одинаковые параметры, один, чтобы сделать ссылку и один, чтобы сделать копии? или в прототипе есть эквивалент автоопределения параметра C ++, поэтому вызывающий не должен указывать его? Я думал об использовании varargs, но тогда вызывающая сторона может отправлять неограниченное количество параметров в качестве мусора, возможно, вызывая переполнение стека, я думаю ...

/**
 * An immutable, double-precision floating-point (64-bit doubles x4) rectangle.
 * The rectangle can be made to reference existing points, or to create new points. Since the points
 * are also immutable, this is acceptable, as it is guaranteed they cannot change.
 * @author Bill
 */
public class DoubleRect {
    public final DoublePoint topLeft;
    public final DoublePoint bottomRight;

    public DoubleRect(DoublePoint setTopLeft, DoublePoint setBottomRight, boolean makeCopies) {
        if(makeCopies == true) {        
            topLeft = new DoublePoint(setTopLeft);
            bottomRight = new DoublePoint(setBottomRight);
        }
        else {
            topLeft = setTopLeft;
            bottomRight = setBottomRight;
        }
    }


}

ОБНОВЛЕНИЕ: Спасибо всем, кто помог мне понять, что делать вместо этого. Вот как я это перекодировал.

/**
 * An immutable, double-precision floating-point (64-bit) rectangle.
 * The rectangle can be made to reference existing points, or to create new points. Since the points
 * are also immutable, referencing the points is acceptable, as it is guaranteed they cannot change.
 * @author Bill
 */
public class DoubleRect {
    public final DoublePoint topLeft;
    public final DoublePoint bottomRight;

    /**
     * This constructor will reference the passed objects rather than duplicating them.
     * See the static factory method createWithClonedPoints() for making internal copies of the point objects
     * @param setTopLeft Double point designating the top left coordinate
     * @param setBottomRight Double point designating the bottom right coordinate
     */
    public DoubleRect(DoublePoint setTopLeft, DoublePoint setBottomRight) {
        topLeft = setTopLeft;
        bottomRight = setBottomRight;
    }

    /**
     * This constructor will create new immutable points within this object using the coordinates specified
     */
    public DoubleRect(double top, double left, double right, double bottom) {
        topLeft = new DoublePoint(left, top);
        bottomRight = new DoublePoint(right, bottom);
    }

    public static DoubleRect createWithClonedPoints(DoublePoint topLeft, DoublePoint bottomRight) {
        return new DoubleRect(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
    }


}

Ответы [ 3 ]

2 голосов
/ 09 ноября 2011

Есть ли способ, которым я могу сделать два конструктора с одинаковыми параметрами, один для создания ссылки и один для копирования?

В таком случае рекомендуется иметь несколько статических фабричных методов вместо конструкторов.

1 голос
/ 09 ноября 2011

Есть ли способ сделать два конструктора с одинаковыми параметрами ...

Нет. В Java каждый конструктор должен иметь свою подпись.

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

Нет, прямого эквивалента нет. Вы могли бы однако к этому:

public DoubleRect(DoublePoint topLeft, DoublePoint bottomRight,
         boolean makeCopies) {
    ...
}

public DoubleRect(DoublePoint topLeft, DoublePoint bottomRight) {
    this(topLeft, bottomRight, false);
}

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


Однако я согласен, что фабричные методы или фабричные объекты могут быть лучшим решением.

0 голосов
/ 09 ноября 2011

почему бы не использовать стратегию полиморфизма, вы можете сделать это так:

public class DoubleRect {
    public final DoublePoint topLeft;
    public final DoublePoint bottomRight;

    public DoubleRect() {
       topLeft = new DoublePoint();
       bottomRight = new DoublePoint();
    }

public DoubleRect(DoublePoint setTopLeft, DoublePoint setBottomRight)
{
   topLeft = setTopLeft;
   bottomRight = setBottomRight;
}


}

Этот тип объявления для вашего конструктора действителен для Java.

...