是否丑陋的设计,我根据参数是子类型还是超类型重载方法?

时间:2017-12-08 15:40:42

标签: java polymorphism override overloading

根据参数是子类型还是超类型,重载方法是否是丑陋的设计?

我打算实现一个超类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());
    }
}

2 个答案:

答案 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