微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – 从抽象类派生时如何服从equals()的合约

约书亚·布洛赫在他的书“有效 Java”中写道,当派生类向检查添加附加字段时,关于equals()的合同发生的陷阱.通常这样会破坏对称性,但Bloch指出“你可以在一个抽象类的子类中添加一个值组件而不会违反equals约定”.

显然,这是真的,因为没有抽象类的实例,所以没有违反的对称性.但是其他子类呢?我写了这个例子,故意省略了哈希码实现和空值检查来保持代码很短:

public abstract class Vehicle {

    private final String color;

    public Vehicle(String color) {
        this.color = color;
    }

    public String getColor() {
        return color;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;

        if (!(o instanceof Vehicle)) return false;

        Vehicle that = (Vehicle) o;

        return color.equals(that.color);
    }

}

public class Bicycle extends Vehicle {

    public Bicycle(String color) {
        super(color);
    }

}

public class Car extends Vehicle {

    private final String model;

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;

        if (!(o instanceof Car)) return false;

        Car that = (Car) o;

        return getColor().equals(that.getColor()) && model.equals(that.model);
    }

}

当我使用相同的颜色字符串创建每个类的一个实例时,equals()的对称性将被破坏:

Bicycle bicycle = new Bicycle("blue");
Car car = new Car("blue","Mercedes");

bicycle.equals(car) <- true
car.equals(bicycle) <- false

我不确定如何处理这个最好的方法.在抽象类中声明equals()作为抽象,以强制执行子类?但是,在抽象类中根本没有声明equals()可以实现相同的效果.

解决方法

Java的等同契约在这样的情况下特别多,最终这一切都成为程序员的偏好和需求的问题.我记得遇到这个同样的问题,我遇到了 this article,考虑到与Java的平等合同时,它出现了几个可能性和问题.它基本上最终说,没有办法适当地做到这一点,而不违反Java等于合同.

在处理抽象类时,我个人的喜好是不要给抽象类一个equals方法.没有意义你不能有两个抽象类型的对象;你应该怎么比较呢?相反,我给每个子类自己的equals,并且运行时处理其余的每当equals()被调用.总的来说,我最经常遵循的文章中提出的解决方案是“只有完全相同的类的对象可能被比较”,这似乎对我来说最为明智.

原文地址:https://www.jb51.cc/java/125526.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐