数字系统类的inheritance层次结构

对于数学表达式的符号表示,我试图构建数字系统类的层次结构。

除了IntegerReal ,我还需要像RationalComplex这样的类。 我希望所有这些类能够相互无缝地互操作。

例如,将Complex添加到Integer将给出Complex等。


我让所有这些都实现了Number接口。 (不是java.lang.Number

为了能够添加不同类型的数量,我尝试制作如下的层次结构。

Integer扩展Rational扩展Real扩展Complex

  • 这使得Integer不必要地存储虚部等。这种开销是不希望的。
  • 允许访问Integer虚部也似乎是不合适的。

任何人都可以建议一个更好的设计,避免开销,仍然可以进行互操作吗?

我宁愿创建一个类似于getRealPart()和getImaginaryPart()的接口。 然后你的整数可以简单地为getImaginaryPart()返回0。 因为你希望Integer“成为”一个复合体,但是你不希望Integer包含Complex的内部实现。

 public interface Numberr { public Numberr plus(Numberr n); public Numberr minus(Numberr n); public Numberr multiply(Numberr n); public Numberr sqrt(); ... public Class getType(); } ///////////////////////////////////////////// public class Integerr implements Numberr { protected BigInteger value; @Override public Numberr plus(Numberr n) { if (n instanceof Integerr) { return value.add(n.value); } else { // in case of more broad argument type, use method of that class return n.plus(this); } } .... } /////////////////////////////////////////////// public class Rational implements Numberr { protected BigInteger numerator; protected BigInteger denominator; @Override public Numberr plus(Numberr n) { if (n instance of Integerr) { return new Rational(numerator.multiply(n.value), denominator); } else if (n instanceof Rational) { return new Rational(numerator.multiply(n.denominator).add(n.numerator.multiply(denominator)), denominator.multiply(n.denominator)); } else { return n.plus(this); } } .... } 

我在这里看不到问题。 实数是一个复数,整数是实数。 复数可以表示为a + bi ,整数是复数,使得a是整数并且b = 0 。 所以每个整数都有b ,它等于0。

但是,您可以考虑使用组合(和接口)而不是inheritance:

 interface Complex { Real a(); Real b(); } interface Real extends Complex { @Override default Real b() { return new Integer(0); } } class Integer implements Real { public Integer(int value) { // ... } @Override public Real a() { return this; } // ... } 

这种方法的缺点是Integer类可以覆盖b()方法,所以可能inheritance会更好,因为你可以在方法上使用final关键字:

 abstract class Complex { abstract Real a(); abstract Real b(); } abstract class Real extends Complex { @Override public final Real b() { return new Integer(0); } } class Integer extends Real { public Integer(int value) { // ... } @Override public Real a() { return this; } // ... } 

我试图自己建模,我想出了下面这个可怕的代码。 由于以下问题,我对此并不满意:

  • InterfaceInterfaceImpl反模式
  • IntegerNumber具有诸如realPart()或者realPart() numerator()denominator()
  • 一些数字(复杂和合理)使用其他数字,而其他数字(实数和整数)使用Java原语

码:

 public class Test { public static void main(String[] args) { ComplexNumber complexOne = new ComplexNumber(new RealNumber(1.25), new RealNumber(3)); ComplexNumber complexTwo = new ComplexNumber(new RealNumber(7), new RealNumber(18.875)); System.out.println("adding two complex numbers:"); System.out.println(complexOne.add(complexTwo)); RealNumber realOne = new RealNumber(15.125); RealNumber realTwo = new RealNumber(7.375); System.out.println("adding two real numbers:"); System.out.println(realOne.add(realTwo)); System.out.println(realTwo.add(realOne)); System.out.println("adding complex and real number:"); System.out.println(complexOne.add(realOne)); System.out.println(realOne.add(complexOne)); RationalNumber rationalOne = new RationalNumber(new IntegerNumber(1), new IntegerNumber(2)); RationalNumber rationalTwo = new RationalNumber(new IntegerNumber(1), new IntegerNumber(3)); System.out.println("adding two rational numbers:"); System.out.println(rationalOne.add(rationalTwo)); IntegerNumber integerOne = new IntegerNumber(6); IntegerNumber integerTwo = new IntegerNumber(7); System.out.println("adding two integers:"); System.out.println(integerOne.add(integerTwo)); System.out.println("adding real number and integer:"); System.out.println(integerOne.add(realOne)); System.out.println(realOne.add(integerOne)); System.out.println("adding complex number and integer:"); System.out.println(integerOne.add(complexOne)); System.out.println(complexOne.add(integerOne)); } } // interfaces interface Complex { Real realPart(); Real imaginaryPart(); default Complex add(Complex other) { return new ComplexNumber( this.realPart().add(other.realPart()), this.imaginaryPart().add(other.imaginaryPart()) ); } } interface Real extends Complex { double asDouble(); @Override default Real imaginaryPart() { return new IntegerNumber(0); } default Real add(Real other) { return new RealNumber(this.asDouble() + other.asDouble()); } } interface Rational extends Real { Integer numerator(); Integer denominator(); @Override default Real realPart() { return new RealNumber(1.0d * numerator().asInt() / denominator().asInt()); } @Override default double asDouble() { return realPart().asDouble(); } default Rational add(Rational other) { return new RationalNumber( this.numerator().multiply(other.denominator()).add(this.denominator().multiply(other.numerator())), this.denominator().multiply(other.denominator()) ); } } interface Integer extends Rational { int asInt(); @Override default Integer numerator() { return new IntegerNumber(asInt()); } @Override default Integer denominator() { return new IntegerNumber(1); } default Integer add(Integer other) { return new IntegerNumber(this.asInt() + other.asInt()); } default Integer multiply(Integer other) { return new IntegerNumber(this.asInt() * other.asInt()); } } // implementations class ComplexNumber implements Complex { private final Real realPart; private final Real imaginaryPart; public ComplexNumber(Real realPart, Real imaginaryPart) { this.realPart = realPart; this.imaginaryPart = imaginaryPart; } @Override public Real realPart() { return realPart; } @Override public Real imaginaryPart() { return imaginaryPart; } @Override public String toString() { return String.format("%s + %si", realPart, imaginaryPart); } } class RealNumber implements Real { private final double value; public RealNumber(double value) { this.value = value; } @Override public Real realPart() { return this; } @Override public double asDouble() { return value; } @Override public String toString() { return "" + value; } } class RationalNumber implements Rational { private final Integer numerator; private final Integer denominator; public RationalNumber(Integer numerator, Integer denominator) { this.numerator = numerator; this.denominator = denominator; } @Override public Integer numerator() { return numerator; } @Override public Integer denominator() { return denominator; } @Override public String toString() { return String.format("%s/%s", numerator, denominator); } } class IntegerNumber implements Integer { private final int value; public IntegerNumber(int value) { this.value = value; } @Override public int asInt() { return value; } @Override public String toString() { return "" + value; } } 

我想知道接口是否应该是实现方法为final的抽象类。 最后,我认为最好只使用简单的inheritance并忽略每个整数都有一个虚部的字段的事实。

我希望这会给你一些想法。