我似乎无法弄清楚为什么当我清楚地覆盖了相等方法时,我总是得到真

I can't seem to figure out why I keep getting true when I clearly overridden the equality method

提问人:Timothy Nguyen 提问时间:2/24/2021 最后编辑:GSergTimothy Nguyen 更新时间:11/28/2021 访问量:54

问:

我试图弄清楚这一点,但我似乎无法正确比较它。

当我尝试在运行时设置代码时,当我需要它来生成错误测试时,结果最终会变成 True。广泛的测试表明它始终是正确的,我不知道如何对它产生错误。

import java.util.Scanner;

public class LandTract
{
    // instance variables
    private static double length , width, area;

    /**
     * Constructor for objects of class LandTract
     */
    public LandTract(double length, double width, double area)
    {
        // initialise instance variables
        length = 0;
        width = 0;
    }

    public LandTract(double length, double width)
    {
        this.length = length;
        this.width = width;
    }
    
    public void setLength(double length)
    {
        this.length = length;
    }
    
    public double getLength()
    {
        return length;
    }
    
    public void setWidth(double width)
    {
        this.width = width;
    }
    
    public double getWidth()
    {
        return width;
    }
    
    public double getArea()
    {
        return area = length * width;
    }
    
    public String toString()
    {
        String str = "Length: " + length + "\nWidth: " + width;
        return str;
    }
    
    public boolean equals(Object obj)
    {
        LandTract land = (LandTract) obj;
        if (this.length != land.length)
            return false;
        if (this.width != land.width)
            return false;
        if (this.area != land.area)
            return false;
        
            return true;
    }
    
    public static void main(String[] args)
    {
        Scanner key = new Scanner(System.in);
        
        System.out.print("Enter the length of the first tract of land: ");
        length = key.nextDouble();
        key.nextLine();
        System.out.print("Enter the width of the first tract of land: ");
        width = key.nextDouble();
        key.nextLine();
        LandTract land1 = new LandTract(length , width);
        System.out.println("The area of the first tract of land is " + land1.getArea());
        System.out.println();
        
        System.out.print("Enter the length of the second tract of land: ");
        length = key.nextDouble();
        key.nextLine();
        System.out.print("Enter the width of the second tract of land: ");
        width = key.nextDouble();
        key.nextLine();
        LandTract land2 = new LandTract(length, width);
        System.out.println("The area of the second tract of land is " + land2.getArea());
        System.out.println();
        
        if (land1.equals(land2))
            System.out.println("Both tracts of land are the same size.");
        else
            System.out.println("They are different sizes.");
    }
}
Java 比较 相等

评论

0赞 Bill the Lizard 2/24/2021
请显示您在测试中使用的值。为了提高可重复性,单元测试会比用户驱动的测试更好。此外,似乎没有设置您的字段,但它包含在您的相等性测试中。area
0赞 Bruno CL 2/24/2021
添加@Override以确保
0赞 xerx593 2/24/2021
static意思是“在所有土地/对象之间共享”......你通过“实例访问器”(getter/setter)设置类变量,因此会造成混淆。从变量声明中删除 ..并在 main 方法中使用“局部变量”(如果有的话)!;)static
0赞 Timothy Nguyen 2/24/2021
感谢大家的帮助,多亏了你们的帮助,我才能够弄清楚。

答:

0赞 xerx593 2/24/2021 #1

令人困惑和具有讽刺意味的错误评论的最好例子:

// instance variables
private static double length , width, area;

当您执行以下操作时,该程序的运行效果要好得多:

  1. (真的)引入实例变量:

    private double length , width, area;
    
  2. 修复 main 方法中的编译器问题(通过声明具有相同标识符的局部变量。没有好的风格,但很快):

    public static void main(String[] args) {
       double length, width;
       // ...
    }
    

评论

0赞 Timothy Nguyen 2/24/2021
所以主要问题是因为我把它弄得太复杂了?非常感谢你,它帮助它工作
0赞 xerx593 2/24/2021
我不确定你是怎么到达那里的。可能重用变量名称(长度、宽度)并避免编译器错误(“make static”)。但是(我希望)你学会了(“困难”的方式):“实例”和“静态”(非实例/类......变量等;)欢迎,萌芽!
0赞 xerx593 2/24/2021
一个简单但很好的问题(用于更深入的研究):stackoverflow.com/q/1215881/592355
0赞 M. Justin 11/28/2021 #2

这里的问题是,被比较的值 (, , 和 ) 是静态字段,而不是实例字段。这意味着对它们的任何引用都将使用相同的全局值,而不管类的哪个实例引用了它们。lengthwidtharea

特别相关的是,在方法中将始终返回 ,因为两者 和 将引用相同的值。(请注意,如果涉及多个线程,则此保证不再成立,但此示例并非如此。this.length != land.lengthequalstruethis.lengthland.length

这也意味着,对构造函数或 setter 的任何调用都将设置共享的静态字段,从而覆盖之前在另一个实例上调用 setter 或构造函数时写入的值。例如,构造函数将覆盖静态 & 字段,而该方法将覆盖静态字段。length, widthlengthwidthsetLengthlength

public LandTract(double length, double width)
{
    this.length = length;
    this.width = width;
}

public void setLength(double length)
{
    this.length = length;
}

解决方法是将这些字段更改为实例字段,而不是静态字段:

public class LandTract
{
    private double length, width, area;

    // [...]
}