По сути, то, что вы ищете, это способ определения абстрактного метода getVar
в родительском классе A
и предоставление реализаций в ваших подклассах B
и C
с родительским классом 'equals
метод в зависимости от значения, возвращаемого getVar
.Это усложняется тем фактом, что каждый подкласс может иметь различный тип возвращаемого значения для getVar
.
. Решение состоит в том, чтобы сделать A
универсальный класс, позволяющий возвращать самому типу возвращаемого значения getVar
родовой.Затем вы можете просто ссылаться на метод getVar
из equals
, не беспокоясь о его конкретном типе:
public abstract class A<T> {
public abstract T getVar();
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getVar().hashCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
A<?> other = (A<?>) obj;
return getVar().equals(other.getVar());
}
}
В приведенном выше примере вы заметите, что getVar
возвращает универсальный тип T
.Это будет указано при определении ваших подклассов:
public class B extends A<Integer> {
private int var = 0;
public B(int var) { this.var = var; }
@Override
public Integer getVar() { return var; }
}
public class C extends A<String> {
private String var = "";
public C(String var) { this.var = var; }
@Override
public String getVar() { return var; }
}
Это все, что нужно!Если вы не решите специально переопределить equals
в своем подклассе, он обратится к методу, объявленному в A
, когда .equals
вызывается для экземпляра вашего подкласса.Полный тестовый пример включен ниже.
public class Tester042219 {
public static void main(String[] args) {
B x = new B(1);
B x2 = new B(1);
B x3 = new B(99);
System.out.println("B == B: Works? "
+ (x.equals(x2) && !x.equals(x3)));
C y = new C("A");
C y2 = new C("A");
C y3 = new C("AAAA");
System.out.println("C == C: Works? "
+ (y.equals(y2) && !y.equals(y3)));
}
public static abstract class A<T> {
public abstract T getVar();
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getVar().hashCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
A<?> other = (A<?>) obj;
return getVar().equals(other.getVar());
}
}
public static class B extends A<Integer> {
private int var = 0;
public B(int var) { this.var = var; }
@Override
public Integer getVar() { return var; }
}
public static class C extends A<String> {
private String var = "";
public C(String var) { this.var = var; }
@Override
public String getVar() { return var; }
}
}