我有一个类层次结构,如下所示......
public class Rectangle2
{
// instance variables
private int length;
private int width;
/**
* Constructor for objects of class rectangle
*/
public Rectangle2(int l, int w)
{
// initialise instance variables
length = l;
width = w;
}
// return the height
public int getLength()
{
return length;
}
public int getWidth()
{
return width;
}
public String toString()
{
return "Rectangle - " + length + " X " + width;
}
}
public class Box2 extends Rectangle2
{
// instance variables
private int height;
/**
* Constructor for objects of class box
*/
public Box2(int l, int w, int h)
{
// call superclass
super(l, w);
// initialise instance variables
height = h;
}
// return the height
public int getHeight()
{
return height;
}
public String toString()
{
return "Box - " + getLength() + " X " + getWidth() + " X " + height;
}
}
public class Cube extends Box2 {
public Cube(int length)
{
super(length, length, length);
}
public String toString()
{
return "Cube - " + getLength() + " X " + getWidth() + " X " + getHeight();
}
}
我想在所有类中添加一个equals()方法,这样如果一个类的输出等于其他类输出,它将打印“Box和Cube具有相同的维度”。我真的很困惑。我所知道的是,我必须使用if-else
声明,但之后我就想不出该做什么。
这是我的问题所要做的: 3.还要为类添加equals()方法,以便根据其维度的值确定两个矩形,框或多维数据集何时相等。 Cube应该继承Box类的equals方法而不是覆盖它。 这是输出应该是这样的: http://i.stack.imgur.com/Kgti1.png
答案 0 :(得分:2)
这是一个坏主意,但您可以在equals
中定义Box2
,如下所示:
public class Box2 extends Rectangle2 {
//...
boolean equals(Object o) {
//a quick check if we are comparing with ourselves
if (this==o) return true;
//no object is equals to null
if (o==null) return false;
//compare only if o is an instance of Box
if (o instanceof Box2) {
(Box2) that = (Box2) o;
if (this.getWidth()!=that.getWidth()) return false;
if (this.getLength()!=that.getLength()) return false;
if (this.getHeight()!=that.getHeight()) return false;
return true;
}
//instances of other classes cannot be equal to this instance
return false;
}
}
由于Cube
延伸equals
,所以具有相同尺寸的任何Box
将等于具有相同尺寸的另一个框。 Cube
是Box
。
为什么这是一个坏主意?假设我们有一个扩展BoxWithColor
的类Box
并添加一个表示框颜色的变量
public class BoxWithColor extends Box {
public String color;
public BoxWithColor(String color, int l, int w, int h) {
super(l,w,h);
this.color=color;
}
}
现在new BoxWithColor("red",1,2,3).equals(new Box(1,2,3))
,这是错误的。
通常,应为同一类的实例保留equals。
答案 1 :(得分:1)
以下是如何做到这一点:
public class Rectangle {
private final int length;
private final int width;
public Rectangle(int length, int width) {
this.length = length;
this.width = width;
}
public int getLength() {
return length;
}
public int getWidth() {
return width;
}
public String toString() {
return "Rectangle - " + length + " X " + width;
}
@Override
public int hashCode() {
return (length * 159) + (width * 523);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Rectangle)) {
return false;
}
Rectangle that = (Rectangle) obj;
return this.hashCode() == that.hashCode();
}
}
覆盖equals时需要覆盖hashCode,因为contract of hashCode表示如果对象相等,hashCode必须相同。 hashCode的实现应尽量避免为不同的对象生成相同的hashCode,但这不是一个硬性要求。因此,这里显示的方法就足够了。 hashCode主要用于在使用像HashMap这样的bucketing系统的数据结构中很好地分配对象,因此对于这种数据结构的性能,如果hashCodes具有良好的传播,它将非常有用。
public class Box extends Rectangle {
private final int height;
public Box(int length, int width, int height) {
super(length, width);
this.height = height;
}
public int getHeight() {
return height;
}
public String toString() {
return "Box - " + getLength() + " X " + getWidth() + " X " + height;
}
@Override
public int hashCode() {
return super.hashCode() + (height * 343);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Box)) {
return false;
}
Box that = (Box) obj;
return this.hashCode() == that.hashCode();
}
}
Box可以调用super.hashCode()并为额外参数' height'添加一个因子。请注意,使用此方法,高度为零的框将具有与具有相同长度和宽度的Rectangle相同的hashCode。这不是必要条件,但在某些条件下可能有用。
public class Cube extends Box {
public Cube(int length) {
super(length, length, length);
}
public String toString() {
return "Cube - " + getLength() + " X " + getWidth() + " X "
+ getHeight();
}
}
Cube可以在Rectangle和Box中完成的工作中徒步。这一切都很好的原因是所有这些类中的字段都是不可变的(例如,没有setter)。我强调了这一点,因为它们都是最终的,因此编译器确实无法更改它们。如果您有setter,则可以创建一个多维数据集,然后将宽度设置为不同的值。这会搞砸这种设计。有关详细信息,请参阅文章'A Square Is Not A Rectangle'