java - 处理继承时重写 equals 方法

标签 java inheritance overriding equals abstraction

我一直在阅读有关在处理子类时如何最好地重写 equals 方法的内容,在这里我发现了很多帖子。他们推荐了使用instanceof或getClass()来比较不同子类的对象来实现解决方案的不同方法。

然而,引用《Effective Java》,我的理解是(我对此很陌生,所以我很可能是错的!)Bloch 认为,最终两者都可能有问题,“没有办法扩展可实例化的类,并且在保留 equals 契约的同时添加一个值组件,除非您愿意放弃面向对象抽象的好处”。然后建议“优先选择组合而不是继承”。

所以我正在处理这个类层次结构:AbstractClass、ConcreteClass1 和 ConcreteClass2。 ConcreteClass1 扩展 AbstractClass,ConcreteClass2 扩展 ConcreteClass1。目前只有 AbstractClass 重写了 equals 方法。

所以在抽象类中:

public abstract class AbstractClass {
        private String id;


        public boolean equals(Object other) {
            return other != null && other.getClass().equals(getClass())
                    && id.equals(((AbstractClass) other).id);
        }

    }

在 ConcreteClass1 中我有:

public class ConcreteClassOne extends AbstractClass
{
  private final AbstractClass parent;

  public ConcreteClassOne( String anId, AbstractClass aParent )
  {
    super( anId );

    parent = aParent;
  }

}

最后在 ConcreteClassTwo 中我有:

public class ConcreteClassTwo extends ConcreteClassOne
{
  private static int nextTrackingNo = 0;

  private final int trackingNo;

  public ConcreteClassTwo ( String anId )
  {
    super( anId, null );

    trackingNo= getNextTrackingNo();
  }
}

所以我相信我需要重写 ConcreteClassOne 和 ConcreteClassTwo 中的 equals 方法以包含重要字段parent和trackingNo。我不允许更改设计,因此不能选择使用组合。有什么建议么?

最佳答案

最简单的方法是在具体类和抽象类中扩展 equals()。

public class ConcreteClassTwo extends ConcreteClassOne {
    public boolean equals(Object other) {
        boolean rv = super.equals( other );
        if ( other instanceof ConcreteClassTwo ) {
           rv = rv && (this.trackingNo == ((ConcreteClassTwo) other).trackingNo);
        }
        return rv;
    }
}

关于java - 处理继承时重写 equals 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16670824/

相关文章:

java - 重复键 - 误导性异常信息?

java - 等于验证与indexOf验证?

java - 在 Tomcat 中自动检测 URI 编码

swift - Swift 3 中通过间接调用调用了错误的专用泛型函数

scala - 重写 Scala 中的密封特征

java - jibx 与 hibernate 5 编码

c++ - 从子调用父方法,类似于调用 "super"(C++)

ios - Obj-C 继承自 SKSpriteNode

mysql - 将多行插入具有 super /子类型的 MySQL 表中

c# - 要用属性或字段覆盖 ToString() 方法?