2

我试图了解“equals()”在 Java 中的工作原理。尤其是与“toString()”相比。这是一个让我偏离正轨的例子。


public class Car
{
    String make, model;

    public Car( String model, String make )
    {
        this.make  = model;
        this.model = make;
    }   

    public String toString()
    {
        String str = "This is a car. ";
        str += "Make: " + make + " | Model: " + model;
        return str;
    }

    public boolean equals( Car c )
    {
        return ( make.equals( c.make ) && model.equals( c.model ) );
    }
}

public class Node 
{
    protected Object obj;
    protected Node next;

    public Node( Object o )
    {
        this.obj = o;
        this.next = null;
    }

    public String toString()
    {
        return obj.toString();
    }

    public boolean equals( Node n )
    {
        return ( this.obj.equals( n.obj ) );
    }
}

Car c1 = new Car("toyota", "corolla");
Car c2 = new Car("toyota", "corolla");

Node nC1 = new Node( c1 );
Node nC2 = new Node( c2 );

nC1.print();
nC2.print();


if( nC1.equals( nC2 ) )
    System.out.println("They are equal!");
else
    System.out.println("They are NOT equal!");

这里 nC1.print() 和 nC2.print() 的行为符合预期。印刷:

This is a car. Make: toyota | Model: corolla
This is a car. Make: toyota | Model: corolla

然而 nC1.equals( nC2 ),打印:

"They are NOT equal!"

简而言之,问题是我可以覆盖“toString()”,但不能覆盖“equals()”。我错过了什么?我认为这种行为有一个简单的解释。

4

4 回答 4

7

我认为您应该将方法的签名保留为:

public boolean equals(Object obj)

附带说明:@Override注释放在要覆盖的方法中,以确保您覆盖了正确的方法,否则编译器会抱怨。

于 2012-07-26T01:18:29.067 回答
4

方法签名是

@Override
public boolean equals(Object o) { ... }

您无法像尝试那样更改参数类型。equals in 的一个有用模式class Foo

@Override
public boolean equals(Object o) {
    if (o instanceof Foo) {
        Foo foo = (Foo)o;
        return <expression testing equality of foo and this> ;
    }
    return false;
}

对于你的例子,

@Override
public boolean equals(Object o)  
{  
    if (o instanceof Car) {
        Car car = (Car)o;
        return this.make.equals(car.make) && this.model.equals(car.model);
    }
    return false;  
}  
于 2012-07-26T01:24:04.020 回答
1

您的方法签名是public boolean equals( Car c ). 因此 Java 不会覆盖该equals(Object)方法;相反,它重载了它。

由于 in 中的equals()方法Node是调用Car.equals(Object),因此它使用不同的实现。

你应该这样做:

public boolean equals( Object o )
{
    Car c = (Car)o;
    return ( make.equals( c.make ) && model.equals( c.model ) );
}
于 2012-07-26T01:21:13.143 回答
0

知道了。感谢大家的有用提示和评论。通过将 Class Car 中的 equals(..) 代码替换为以下代码,代码可以正常工作:

public boolean equals( Object o )
{
    if( o instanceof Car )
    {
        if( make.equals( ((Car)o).make ) && model.equals( ((Car)o).model ) )
            return true;
        else
            return false;
    }
    else
        return false;
}
于 2012-07-26T02:01:40.310 回答