@Alex_java

Как правильно переопределить метод equals при наследовании?

Всем привет.
Правильно ли я понял стратегию реализации метода equals при наследовании классов (ниже приведен пример реализации)?

class A {
        int a = 1;

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

            A a1 = (A) o;

            return a == a1.a;

        }
    }

    class B extends A {
        int b = 1;

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

            // Ошибка - нарушен принцип подстановки Барбары Лисков
            // if (o == null || getClass() != o.getClass()) return false;

            if (!(o instanceof A)) return false;
            if (!super.equals(o)) return false;

            if(o instanceof B) {
                B b1 = (B) o;
                return b == b1.b;
            }

            return true;
        }
    }

    @Test
    public void testEquals() {
        A a = new A();
        B b = new B();
        System.out.println(a.equals(b)); // true
        System.out.println(b.equals(a)); // true
    }
  • Вопрос задан
  • 938 просмотров
Пригласить эксперта
Ответы на вопрос 2
@sirs
Спорный вопрос, но Josh Bloch с вами согласен.
С другой стороны нарушен принцип симметричности equals.
В любом случае, серебрянной пули не существует, а отдельные решения отлично подходят в каждом конкретном случае.
Ответ написан
Комментировать
targetjump
@targetjump
Впринципе задумка верная, можно сделать немного красивее

//..
if (!(o instanceof A) {
    return false;
}
if (!(o instanceof B)) {
    return this.equals(o);
}
//..


Нету правильного способа ибо вы всегда будете нарушать что то(транзитивность в данном случае).
Из Effective Java 2nd edition item8:
There is no way to extend an instantiable class and add a value component while preserving the equals contract


Часто можно просто пересмотреть подход и использовать композицию вместо наследования.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы