有 Java 编程相关的问题?

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

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

我一直在阅读关于在处理子类时如何最好地重写equals方法的文章,在这里我发现了不少帖子。他们建议使用instanceof或getClass()实现解决方案的不同方法来比较不同子类的对象

然而,关于有效的Java,我的理解是(我对这一点还不熟悉,所以我很可能是错的!)布洛赫认为,最终两者都会有问题,“除非你愿意放弃面向对象抽象的好处,否则没有办法在保留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);
        }

    }

在第1课中,我有:

public class ConcreteClassOne extends AbstractClass
{
  private final AbstractClass parent;

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

    parent = aParent;
  }

}

最后,在第二课中,我有:

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

  private final int trackingNo;

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

    trackingNo= getNextTrackingNo();
  }
}

所以我认为我需要重写ConcreteClassOne和ConcreteClassII中的equals方法,以包括有效字段parent和trackingNo。我不允许改变设计,所以不能使用合成。有什么建议吗


共 (1) 个答案

  1. # 1 楼答案

    如果equalsConcreteClassOneConcreteClassTwo中都有equals,则equals的对称性被破坏:

    Object c1 = new ConcreteClassOne(),
           c2 = new ConcreteClassTwo();
    System.out.println("c1=c2? " + c1.equals(c2)");
    System.out.println("c2=c1? " + c2.equals(c1)");
    

    现在,如果您以通常的方式实现equals,这将打印出来

    true
    false
    

    因为在c2.equals中有instanceof ConcreteClassTwo,对于c1失败,但在相反的情况下,类似的检查通过