以下是此作业的5个类别之一的选定代码。
每个类必须有一个equals()方法,可以将其类的对象与任何和所有5个类的对象进行比较。
我的策略是为了精确,将每个对象值转换为double。
当每个类扩展Number时,每个类都有一个doubleValue()方法可供使用。
除非我在执行doubleValue()
之前将x类型化为RationalN,否则代码将无法编译但是当执行代码时,它会在比较另一个类的对象时进行抱怨,因为它不能被类型化为该类。
我从哪里开始?
public class RationalN extends Number{
private int numerator;
private int denominator;
public RationalN(int x, int y){
if (y == 0){
throw new ArithmeticException("cannot devide by zero");
} else {
this.numerator=x;
this.denominator=y;
}
}
public double doubleValue(){
double value = (double)numerator/(double)denominator;
return (double)value;
}
public boolean equals(Object x){
if (((RationalN)x).doubleValue() == this.doubleValue()){
return true;
} else {
return false;
}
}
答案 0 :(得分:3)
根据我从帖子中得到的内容,您要检入等于对象表示的数值是否等于参数对象的数值。因此,比较这些类不是合适的。相反,你的equals()方法也看起来像这样:
public boolean equals(Object x) {
if(this == x)
return true;
if(x == null)
return false;
if(!(x instanceof Number))
return false;
Number n = (Number)x;
return (n.doubleValue() == this.doubleValue());
}
然而,这违反了equals()合同: 新的RationalN(1,1).equals(new Integer(1))将返回true,但是新的Integer(1).equals(new RationalN(1,1));不会 - 上面的equals()方法违反了对称性。因此,引入一个实现Number(例如,MyNumber)的抽象类是合适的,它由五个类扩展 并以上述方式实现equals()(使用instanceof MyNumber)。
答案 1 :(得分:1)
编辑:我刚才意识到这个数字在Number类中有doubleValue()
作为抽象方法。好的,这是完美的。只需在这五个类中实现equals。或者,如果Number不需要作为抽象类,那么请阅读下面的内容,看看您是否可以创建自己的抽象类来实现equals()
并保存重复的代码。
public boolean equals(Object x)
{
if(x instanceof Number == false)
return false;
Number other = (Number) x;
return other.doubleValue() == doubleValue();
}
你无法在平等中做你正在做的事情的原因是因为你正在将你想要比较的任何东西与RationalN类进行比较。当这对不是RationalN的类完成时,会导致ClassCastException。
由于所有类都扩展了Number并且doubleValue()
被声明为Number可用的方法,现在可以将这些类强制转换为Number(如果它们是Number的实例),然后从那里访问该方法。
我希望这是有道理的。我鼓励你阅读接口和多态。
编辑:顺便说一句,如果您不需要扩展Number,您可以创建一个抽象类,其中包含抽象方法doubleValue()
,然后您可以提供equals的具体实现(我在上面提供) )在抽象类中。然后让所有五个类扩展抽象类。然后他们将各自实现自己的doubleValue()
版本,但会共享抽象类中定义的equals()
,从而消除equals()
到所有五个类的复制/粘贴。如果您不必扩展数字,这将是理想的路线。