根据参数是子类型还是超类型,重载方法是否是丑陋的设计?
我打算实现一个超类A和一个子类B,这些对象可以相互比较。
compareTo在A类和B类中都被重载了两次,代码看起来有点混乱。 感觉就像丑陋的设计。我不确定是否有更优雅的方法。
class A implements Comparable<A> {
private Integer x;
public A(Integer i) {
x = i;
}
public Integer getX() {
return x;
}
public int compareTo(A other) {
return x.compareTo(other.getX());
}
public int compareTo(B other) {
return x.compareTo(other.getX() + other.getY());
}
}
class B extends A {
private Integer y;
public B(Integer a, Integer b) {
super(a);
y = b;
}
public Integer getY() {
return y;
}
@Override
public int compareTo(A other) {
return Integer.compare(this.getX() + y, other.getX());
}
@Override
public int compareTo(B other) {
return Integer.compare(this.getX() + y, other.getX() + other.getY());
}
}
答案 0 :(得分:2)
是的,这是一个糟糕的设计。这样的事情会更好。
class A implements Comparable<A> {
private Integer x;
public A(Integer i) {
x = i;
}
public Integer getX() {
return getX();
}
protected Integer compareValue() {
return getX();
}
@Override
public int compareTo(A other) {
return compareValue().compareTo(other.compareValue());
}
}
class B extends A {
Integer y;
public B(Integer a, Integer b) {
super(a);
y = b;
}
public Integer getY() {
return y;
}
@Override
protected Integer compareValue() {
return getX() + getY();
}
}
答案 1 :(得分:2)
设计糟糕,是的。具体而言,它违反了传递性。来自Comparable
Javadocs:
实现者还必须确保关系具有传递性:
(x.compareTo(y)>0 && y.compareTo(z)>0)
隐含x.compareTo(z)>0
。
当你引入继承时,你会失去传递性。这是因为您的A.compareTo(B)
方法实际上并未覆盖任何内容,因此如果您将List<A>
传递给Collections.sort()
,其中包含A
和{{{} 1}},最终会使用B
实例的A.compareTo(A)
方法和A
实例的B.compareTo(A)
方法。在您编写它们时,它们不传递,因此会导致不可预测的顺序,因为反转比较可能会更改排序顺序。
我写了类似的回复w.r.t. B
以及为什么你可以暂时超载它,你可以找到here。