Java 数字系统类的继承层次结构

Java 数字系统类的继承层次结构,java,oop,inheritance,Java,Oop,Inheritance,对于数学表达式的符号表示,我试图构建数字系统类的层次结构 除了Integer和Real,我还需要Rational和Complex之类的类。我希望所有这些类都能无缝地相互操作 e、 g.将复数数字添加到整数将得到一个复数数字等 我让它们都实现了Number接口。(不是java.lang.Number) 为了能够添加不同类型的数字,我尝试了如下的层次结构 IntegerextendsRationalextendsRealextendsComplex 这使得整数不必要地存储虚部等。这种开销是不需要

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

除了
Integer
Real
,我还需要
Rational
Complex
之类的类。我希望所有这些类都能无缝地相互操作

e、 g.将
复数
数字添加到
整数
将得到一个
复数
数字等


我让它们都实现了
Number
接口。(不是
java.lang.Number

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

Integer
extends
Rational
extends
Real
extends
Complex

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


有谁能建议一种更好的设计,在这种设计中可以避免开销,并且互操作仍然是可能的?

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

我认为这里没有问题。实数是复数,整数是实数。复数可以表示为
a+bi
,整数是复数,因此
a
是整数,
b=0
。所以每个整数都有
b
,它等于0

你可以考虑在继承上使用组合(和接口):

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()
方法,因此继承可能会更好,因为您可以在方法上使用
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;
    }

    // ...

}
我自己也尝试过对它进行建模,我在下面给出了这个糟糕的代码。我对此不满意,因为以下问题:

  • Interface
    -
    InterfaceImpl
    反模式
  • IntegerNumber
    的方法有
    realPart()
    分子()
    分母()
  • 一些数字(复数和有理数)使用其他数字,而另一些数字(实数和整数)使用Java原语
代码:

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

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

公共接口编号r{
public interface Numberr {
    public Numberr plus(Numberr n);
    public Numberr minus(Numberr n);
    public Numberr multiply(Numberr n);
    public Numberr sqrt();
    ...

    public Class<? extends Numberr> 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);
       }
   }

   ....

}
公共号码加(号码n); 公共编号R减(编号n); 公共数字乘法(数字n); 公共编号r sqrt(); ...
公共类为什么不使用这样的东西呢?不仅仅是不必要的存储,而且还允许访问虚拟部分。公共数学不允许像我上面描述的那样进行互操作。我根本不会进行这样的层次结构,只需实现公共接口并在其上执行操作。使
整数
扩展
实数
是一个很好的选择d想法是真实的(通常情况下是不理性的)需要一些特殊的内部表示,所以应该根据它执行操作。@最后感谢您的输入。允许访问也是一个坏主意。我已经相应地编辑了这个问题。如果真实部分不合理怎么办?您应该如何返回它?返回类型可以是任何类型。所以我猜是“真实的”或者类似的东西。公共接口需要整数、实数和有理数的单一返回类型。缺少这种统一的返回类型本身就是建立这种层次结构的目的。@TanmayPatil您可以定义检查或返回“最小类型”单一返回类型的方法吗?不确定您的意思(特定方法的返回类型?)?谢谢你的建议。你能告诉我,在这种方法中,添加不同类型的数字如何才能得到正确的返回类型吗?嗯……这很棘手。只要我们使
复杂
类可实例化(即非抽象类),每个整数都会有一个字段
b
,这是我理解您想要避免的。所以我们必须使用接口,但我们最终将使用
InterfaceName
-
InterfaceNameImpl
反模式。我将继续编辑我的答案。正是如此。期待您的答案。非常感谢您的时间。
public interface Numberr {
    public Numberr plus(Numberr n);
    public Numberr minus(Numberr n);
    public Numberr multiply(Numberr n);
    public Numberr sqrt();
    ...

    public Class<? extends Numberr> 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);
       }
   }

   ....

}