Java - 实施 Cloneable 还是添加构造函数?

Java - Implement Cloneable or add a constructor?

嘿,我实际上是在 Java、

上使用自定义 Vector class
public class Vector {

    private double X;
    private double Y;

    public Vector(double x, double y) {
        this.X = x;
        this.Y = y;
    }

    public void setX(double x) {
        this.X = x;
    }
    public double getX(double x) {
        return this.X;
    }

    public void setY(double y) {
        this.Y = y;
    }
    public double getY(double y) {
        return this.Y;
    }

}

我想添加 multiply() 方法,该方法 return 这个向量 * 按指定的因子,

public void multiply(double factor) {
    this.X *= factor;
    this.Y *= factor;
}

问题是,当我使用需要矢量的函数时,我想像这样使用它

doSomething(ancientVector.multiply(-1D));

但是 jvm 不满意,因为我发送给函数的 arg 是 void...

我该怎么做才能让它变得干净,我应该实现 Cloneable 还是创建另一个按照 multiply 的方式工作的构造函数?

doSomething(ancientVector.multiply(-1D));

或添加

public Vector(Vector previous, double mFactor) {
    this.X *= previous.getX() * mFactor;
    this.Y *= previous.getY() * mFactor;
}

我会保持 class 不变,return 一个新的 Vector:

public Vector multiply(double factor) {
    return new Vector(X * factor, Y * factor);
}

你可以像@Basti 说的那样做,或者你也可以 return 你的 Vector 的一个新实例:

public Vector multiply(double factor) {
    return new Vector (this.X * factor, this.Y * factor);
}

这样,当对乘法函数的结果进行任何更改时,它不会影响初始矢量对象。

您的 Vector 将有各种操作(您已经从乘法开始)并且它的用法看起来类似于 Java API classes,例如 BigDecimal。因此,我建议效仿它,并使 class 不可变。这意味着它的所有字段都应该是最终的:

public class Vector {
    private final double x, y;              // Note: final. And use lowercase.

    public Vector(double x, double y) {
        this.x = x;
        this.y = y;
    }

    // Note: no setters!

    public double getX() {                  // Note: no argument.
        return x;
    }

    public double getY() {
        return y;
    }

    public Vector multiply(double factor) {
        return new Vector(x*factor, y*factor);
    }

}

不可变 classes 的优点之一是它们完全基于值,因此您不必担心复制构造函数或克隆。 (顺便说一句,现在几乎从未使用过 Cloneable——复制构造函数是首选——也许数组除外。)不用复制,只需使用赋值:Vector secondVector = firstVector;.