不変性を保証するためにはサブクラスを作らせない必要があり以下のようにfinalクラスとした。
public final class Complex { private final double re; private final double im; public Complex(double re, double im) { this.re = re; this.im = im; } public double realPart() { return this.re; } public double imaginaryPart() { return this.im; } public Complex add(Complex c) { return new Complex(this.re + c.re, this.im + c.im); } public Complex subsract(Complex c) { return new Complex(this.re - c.re, this.im - c.im); } public Complex multiply(Complex c) { return new Complex(this.re * c.re - this.im * c.im, this.re * c.im + this.im * c.re); } public Complex divide(Complex c) { return new Complex( (this.re * c.re + this.im * c.im) / (c.re * c.re + c.im * c.im), (this.im * c.re - this.re * c.im) / (c.re * c.re + c.im * c.im) ); } @Override public boolean equals(Object o) { if(o == this) { return true; } if(!(o instanceof Complex)) { return false; } Complex c = (Complex) o; return Double.compare(this.re, c.re) == 0 && Double.compare(this.im, c.im) == 0; } @Override public int hashCode() { int result = 17 + hashDouble(this.re); result = 31 * result + hashDouble(this.im); return result; } private static int hashDouble(double value) { long longBits = Double.doubleToLongBits(value); return (int) (longBits ^ (longBits >>> 32)); } @Override public String toString() { return "(" + this.re + " + " + this.im + "i" + ")"; } }
また以下のようにstaticファクトリーメソッドを用いる事でも可能である。
public class Complex { private final double re; private final double im; private Complex(double re, double im) { this.re = re; this.im = im; } public static Complex valueOf(double re, double im) { return Complex(re, im); } }
publicやprotectedのコンストラクタを持たないクラスを他のパッケージから拡張することはできない。