2017-12-08 6 views
0

引数がサブタイプかスーパータイプかによってメソッドをオーバーロードするのは醜いですか?引数がサブタイプかスーパータイプかによってメソッドをオーバーロードするのは醜いですか?

私は、スーパークラスAとサブクラスBを暗示するつもりであり、オブジェクトは互いに比較できます。

compareToはクラスAとクラスBの両方で2回オーバーロードされており、コードはちょっと混乱しているようです。 醜いデザインのように感じます。より洗練されたアプローチがあるかどうかはわかりません。

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

はい、それは悪いデザインです。このような何かが良いでしょう。

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(); 
    } 
} 
2

はい、悪いデザインです。具体的には、推移性に違反します。 Comparable Javadocsから:

実装も関係が推移的であることを確認する必要があります(x.compareTo(y)>0 && y.compareTo(z)>0)x.compareTo(z)>0を意味します。

継承を導入すると、推移性が失われます。あなたのA.compareTo(B)方法は実際には何をオーバーライドしていない、とあなたはABの両方を含んでいCollections.sort()List<A>を通過した場合ので、それはAインスタンスのA.compareTo(A)方法とBインスタンスのB.compareTo(A)方法を使用して終了だろうからです。書いたように、ではなくであり、比較を逆順にするとソート順が変わる可能性があるため、予測できない順序が発生します。

私は同様のレスポンスw.r.tを書きました。 Object.equalsとなっています。なぜそれをやり直すことができないのですか。それはhereです。

+0

ありがとうございました。それはとても役に立ちます。改善するためにコードを再構成する方法を知ってもいいですか?ありがとうございます – CodingNow

+1

OldCurmudgeonの再構成は、サブクラスのどれもがあなたの 'compareTo'メソッドをオーバーライドして、何か異なることをしない限り、機能します。 'compareTo'メソッドを' final'にすることでそれを強制することができます。 – Brian

関連する問題