Переопределите equals и hashCode методы в суперклассе или в подклассе или переопределите в обоих - PullRequest
0 голосов
/ 12 декабря 2011

Я относительно новичок в программировании на Java, и у меня возникла проблема с поиском, где использовать равенства и переопределение метода хеш-кода, когда у меня есть подкласс, наследующий от суперкласса.

Я хочу проверить на равенство для объектов суперкласса и подкласса и хотел узнать, нужно ли какому-либо суперклассу и подклассу переопределять их методы equals и hashcode?

В моем подклассе нет переменных экземпляра, а в моем суперклассе есть 2 переменные экземпляра (целые числа)

Мой конструктор подкласса вызывает конструктор суперкласса.

Если я хочу переопределить подклассВозможны ли методы equals и hashcode на основании того факта, что у подкласса нет переменных экземпляра, но он наследует 2 переменные экземпляра от своего суперкласса?

Ответы [ 4 ]

3 голосов
/ 12 декабря 2011

Это на самом деле поднимает сложный вопрос.Допустим, у вас есть класс Foo и два подкласса, FooA и FooB.Имеет ли смысл, в вашем приложении / домене , чтобы FooA когда-либо был равен Foo или FooB?

Если это так, вы должны реализовать equals в суперклассе.И тест на instanceof Foo.По сути, любые дополнительные поля, добавленные в FooA или FooB, будут игнорироваться.Часто это правильно.Код выглядит следующим образом:

public boolean equals(Object o) {  // perfectionists will make this final
  if (this == o)
     return true;
  if (o instanceof Foo) {  // note that Foo, FooA and FooB would all pass
     Foo oFoo = (Foo)o;
     // compare all the fields of Foo here
  }

  return false;
}

Если нет, вам нужно реализовать равенства в подклассах.И тест для классов будет равным, а не просто instanceof.например,

public boolean equals(Object o) {
  if (this == o)
     return true;
  if (o == null)  // this extra check is needed to avoid a NPE
    return false;
  if (o.getClass() == this.getClass()) {  // must be an exact match
     FooA oFoo = (FooA)o;
     // compare all the fields here
  }

  return false;
}

В целом, я думаю, что большинство людей используют первый подход.И это кажется наиболее подходящим для вашей проблемы.См. Эффективная Java Джоша Блоха.Вы найдете много сообщений по этому вопросу, например, Есть ли причина предпочитать getClass (), а не instanceof при генерации .equals ()?

0 голосов
/ 12 декабря 2011

Поскольку в подклассе нет новых атрибутов, переопределение equals() и hashcode() в суперклассе будет в порядке.Когда вы вызываете эти методы для объектов подкласса, методы суперклассов будут вызываться не из класса Object

Однако, если позднее добавятся новые атрибуты в подкласс, вам нужно будет переопределить эти методыв подклассе также.

0 голосов
/ 12 декабря 2011

Если я хочу переопределить методы подкласса equals и hashcode, то это возможно на основании того факта, что подкласс не имеет переменных экземпляра, но наследует 2 переменные экземпляра от своего суперкласса?

Это, конечно, возможно , но это редко имеет смысл. Обратите внимание, что контракт equals() требует, чтобы он был симметричным , то есть a.equals(b) и b.equals(a) всегда должны иметь одинаковый результат. Когда a и b являются экземплярами подкласса и суперкласса, которые по-разному определяют equals(), этот контракт, вероятно, не сохраняется. Это означает, что если вы поместите экземпляры двух классов в коллекцию, коллекция может работать некорректно.

0 голосов
/ 12 декабря 2011

Вам необходимо переопределить их для класса, чей объект будет находиться под проверкой equals() во время выполнения или чей объект будет / может находиться под структурой данных на основе хеширования

...