有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

矩形和长方体类中的java equals()方法

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

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()方法,以便根据两个矩形、长方体或立方体的尺寸值确定它们何时相等。多维数据集应该继承Box类的equals方法,而不是重写它。 这就是输出的方式: http://i.stack.imgur.com/Kgti1.png


共 (2) 个答案

  1. # 1 楼答案

    这是一个坏主意,但您可以在Box2中定义equals,如下所示:

    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将等于具有相同维度的另一个框。ACube是ABox

    为什么这是个坏主意假设我们有一个类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

  2. # 2 楼答案

    以下是如何做到这一点:

    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主要用于在使用bucketing系统(如HashMap)的数据结构中很好地分布对象,因此,对于此类数据结构的性能,如果hashCode具有良好的扩展性,则非常有用

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

    盒子可以叫超级。hashCode()并为额外参数“height”添加一个因子。请注意,使用这种方法,高度为零的框将具有与长度和宽度相同的矩形相同的哈希代码。这不是要求,但在某些情况下可能有用

    public class Cube extends Box {
    
        public Cube(int length) {
            super(length, length, length);
        }
    
        public String toString() {
            return "Cube - " + getLength() + " X " + getWidth() + " X "
                    + getHeight();
        }
    }
    

    立方体可以在长方形和长方形的基础上继续工作。这一切运行得如此顺利的原因是所有这些类中的字段都是不可变的(例如,没有setter)。我强调了这一点,使它们都是最终的,这样编译器才能真正确保它们不能被更改。如果您有setter,您可以创建一个立方体,然后将宽度设置为不同的值。这会把这个设计搞砸的。有关更多信息,请参阅文章'A Square Is Not A Rectangle'