-2

我有一个类层次结构,如下所示......

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 and Cube has the same dimension”。我真的很困惑。我所知道的是我必须使用一个if-else声明,但在那之后我就是想不出该怎么做。

这就是我的问题所说的: 3. 还向类添加一个 equals() 方法,以便您可以根据它们的尺寸值确定两个矩形、框或立方体何时相等。Cube 应该继承 Box 类的 equals 方法而不是重写它。输出应该是这样的:http: //i.stack.imgur.com/Kgti1.png

4

2 回答 2

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;
  }

}

由于Cubeextends equals,任何Box具有相同尺寸的盒子都将等于另一个具有相同尺寸的盒子。ACube是一个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 应该保留给同一个类的实例

于 2013-03-20T04:49:49.503 回答
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,因为hashCode 的约定规定如果对象相等,则 hashCode 必须相同。hashCode 的实现应该尽量避免为不同的对象生成相同的 hashCode,但这不是硬性要求。因此,此处显示的方法就足够了。hashCode 主要用于在使用像 HashMap 这样的分桶系统的数据结构中很好地分布对象,因此对于此类数据结构的性能,如果 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”添加一个因子。请注意,使用这种方法,高度为零的框将具有与具有相同长度和宽度的矩形相同的 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 中完成工作。这一切运行良好的原因是所有这些类中的字段都是不可变的(例如,没有设置器)。我通过将它们全部设为最终版本来强调这一点,因此编译器确实确保它们不能被更改。如果你有设置器,你可以创建一个立方体,然后将宽度设置为不同的值。这会搞砸这个设计。有关更多信息,请参阅文章“正方形不是矩形”

于 2013-03-20T09:27:19.643 回答