Есть ли определенное правило о как Переопределение equals()
& hashCode()
в sub классах, рассматривая супер поля?? знание, что существует много параметров: супер поля являются частными/общедоступными, с/без методом get...
Например, Netbeans генерировал, равняется (), и хэш-код () не рассмотрит супер поля... и
new HomoSapiens("M", "80", "1.80", "Cammeron", "VeryHot").equals(
new HomoSapiens("F", "50", "1.50", "Cammeron", "VeryHot"))
возвратит true: (
public class Hominidae {
public String gender;
public String weight;
public String height;
public Hominidae(String gender, String weight, String height) {
this.gender = gender;
this.weight = weight;
this.height = height;
}
...
}
public class HomoSapiens extends Hominidae {
public String name;
public String faceBookNickname;
public HomoSapiens(String gender, String weight, String height,
String name, String facebookId) {
super(gender, weight, height);
this.name = name;
this.faceBookNickname = facebookId;
}
...
}
Если Вы хотите видеть, что сгенерированные Netbean равняются () и хэш-код ():
public class Hominidae {
...
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Hominidae other = (Hominidae) obj;
if ((this.gender == null) ? (other.gender != null) : !this.gender.equals(other.gender)) {
return false;
}
if ((this.weight == null) ? (other.weight != null) : !this.weight.equals(other.weight)) {
return false;
}
if ((this.height == null) ? (other.height != null) : !this.height.equals(other.height)) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 5;
hash = 37 * hash + (this.gender != null ? this.gender.hashCode() : 0);
hash = 37 * hash + (this.weight != null ? this.weight.hashCode() : 0);
hash = 37 * hash + (this.height != null ? this.height.hashCode() : 0);
return hash;
}
}
public class HomoSapiens extends Hominidae {
...
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final HomoSapiens other = (HomoSapiens) obj;
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
return false;
}
if ((this.faceBookNickname == null) ? (other.faceBookNickname != null) : !this.faceBookNickname.equals(other.faceBookNickname)) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 7;
hash = 89 * hash + (this.name != null ? this.name.hashCode() : 0);
hash = 89 * hash + (this.faceBookNickname != null ? this.faceBookNickname.hashCode() : 0);
return hash;
}
}
Дети не должны рассматривать частных членов своих родителей
, но , очевидно, , все значимые поля следует учитывать для равенства и хеширования.
К счастью, вы можете легко удовлетворить оба правила.
Предполагая, что вы не застряли с использованием сгенерированных NetBeans Equals и HASHCODE, вы можете изменить метод SominiDae Socals для использования экземпляров сравнения, а не равенства класса, а затем использовать его прямолировку. Что-то вроде этого:
@Override
public boolean equals(Object obj) {
if (obj == null) { return false; }
if (getClass() != obj.getClass()) { return false; }
if (! super.equals(obj)) return false;
else {
// compare subclass fields
}
, конечно, Hashcode легко:
@Override
public int hashCode() {
int hash = super.hashCode();
hash = 89 * hash + (this.name != null ? this.name.hashCode() : 0);
hash = 89 * hash + (this.faceBookNickname != null ? this.faceBookNickname.hashCode() : 0);
return hash;
}
серьезно, хотя и: что случилось с NetBeans, не принимая вклад в SuperClass на счет, вызывая методы SuperClass?
Я предпочитаю использовать EqualsBuilder (и HashcodeBuilder) от пакет Ленга свободного городского населения для создания, мой равняется () и хэш-код () методы, намного легче читать.
Пример:
public boolean equals(Object obj) {
if (obj == null) { return false; }
if (obj == this) { return true; }
if (obj.getClass() != getClass()) {
return false;
}
MyClass rhs = (MyClass) obj;
return new EqualsBuilder()
.appendSuper(super.equals(obj))
.append(field1, rhs.field1)
.append(field2, rhs.field2)
.append(field3, rhs.field3)
.isEquals();
}
Правила:
из объекта. ) .
Итак, используйте поля, необходимые для выполнения правил.
Это звучит, как ваш родительский (супер) класс не отменяет равных. Если это так, то необходимо сравнить поля из родительского класса при переопределении этого метода в подкласс. Я согласен, что использование Commons Equalsbuiler - это способ пойти, но вам нужно быть осторожным, что вы не нарушаете симметрию / трансваторные части контракта равен.
Если ваш подкласс добавляет атрибуты на родительский класс, и родительский класс не аннотация и переопределения равен, что вы собираетесь войти в неприятность. В этом сценарии вы должны действительно посмотреть на композицию объекта вместо наследования.
Я настоятельно рекомендую раздел в эффективной Java by Jowsua Block на этом. Это всеобъемлющее и действительно хорошо объяснено.
Поскольку наследование разбивает инкапсуляцию, подклассы, которые реализуют равную () и hashcode (), обязательно должны учитывать особенности их суперклассов. У меня были успех, кодирующие вызовы на методах () и hashcode () класса () и hashcode () из методов подкласса.
Вообще говоря, реализующие равные подклассы, трудно сохранить симметричное и транзитивное.
Рассмотрим суперкласс, который проверяет поле x
и Y
, а также проверки подкласса x
, y
и z
.
Таким образом, подкласс == SuperClass == подкласс, где Z отличается между первым экземпляром подкласса и вторым, нарушающим переходную часть контракта.
Это, почему типичная реализация равна будет проверять GetClass ()! = Obj.getclass ()
вместо того, чтобы делать экземпляр. В приведенном выше примере, если подкласс или суперкласс делает экземпляр проверки, он сломал бы симметрию.
Итак, в том, что подкласс, безусловно, может учитывать Super.equals (), но также должен сделать свой собственный чек GetClass (), чтобы избежать вышеуказанных проблем, а затем проверять наличие равных полей. Это была бы странная утка класса, которая изменила свои собственные равные поведения на основе определенных полей суперкласса, а не только если суперкласс возвращается равным.