2011-11-08 7 views
1

以下は、この割り当てのための5つのクラスの中から選択されたコードです。異種オブジェクトを許可するequals()メソッドのオーバーライド

各クラスには、そのクラスのオブジェクトを5つのクラスの任意のオブジェクトおよびすべてのオブジェクトと比較できるequals()メソッドが必要です。

私の戦略は、正確さのために各オブジェクト値を倍精度に変換することです。

各ClassはNumberを継承するため、各クラスにはdoubleValue()メソッドがあります。

IはのdoubleValueを(実行前RationalN xを型変換しない限り、コードはコンパイルされないであろう)

しかし、それはそのクラスに型変換することができないような別のクラスのオブジェクトを比較すると訴えるコードを実行します。

ここからどこに行くのですか?

 public class RationalN extends Number{ 
      private int numerator; 
      private int denominator; 

      public RationalN(int x, int y){ 
      if (y == 0){ 
       throw new ArithmeticException("cannot devide by zero"); 
      } else { 
       this.numerator=x; 
       this.denominator=y; 
      } 
      } 

      public double doubleValue(){ 
      double value = (double)numerator/(double)denominator; 
      return (double)value; 
      } 

      public boolean equals(Object x){ 
      if (((RationalN)x).doubleValue() == this.doubleValue()){ 
        return true; 
       } else { 
        return false; 
      } 
     } 
+0

あなたはどのクラスをeq​​uals()関数の有効な引数として受け入れる準備ができていますか? –

+0

'x'が' this'と同じクラスを持っていることを確認します。 'x'がnullでなく、' x.getClass()== this.getClass() 'の場合、それらは同じクラスです。あなたのクラスが 'final'の場合、' instanceof'も動作します。 –

+0

他のクラスも 'java.lang.Number'を拡張していますか?スーパークラス 'Number'が実装するために必要な他の抽象メソッドはどうでしょうか? – Gevorg

答えて

3

あなたの投稿から得たものから、オブジェクトが表す数値が引数オブジェクトの数値と等しいかどうかをチェックしたいとします。したがって、クラスを比較するとではなく、が適切です。代わりに、あなたのequals()メソッドは次のようなものになりすぎています

public boolean equals(Object x) { 
    if(this == x) 
     return true; 
    if(x == null) 
     return false; 
    if(!(x instanceof Number)) 
     return false; 
    Number n = (Number)x; 
    return (n.doubleValue() == this.doubleValue()); 
} 

これを、しかし、等号()契約違反: 新しいRationalN(1、1).equals(新しい整数(1))だろうtrueを返しますが、新しいInteger(1).equals(新しいRationalN(1,1));上記のequals()メソッドは対称性に違反します。したがって、あなたの5つのクラスによってしか拡張されず、上記の方法で(instanceof MyNumberを使用して)equals()を実装するNumber(例えば、MyNumber)を実装する抽象クラスを導入するのが適切です。

+0

+1は、同等の契約違反に言及しています –

1

編集:私はその番号が抽象メソッドとしてNumberクラスにdoubleValue()であることを認識しました。これは完璧です。このように5つのクラスすべてでequalsを実装するだけです。代わりにNumberが抽象クラスとして必須でない場合は、equals()を実装する独自の抽象クラスを作成し、重複したコードを保存できることを確認するために、以下をお読みください。

public boolean equals(Object x) 
{ 
    if(x instanceof Number == false) 
    return false; 

    Number other = (Number) x; 

    return other.doubleValue() == doubleValue(); 
} 

あなたはRationalNクラスへと比較しようとしているものは何でもキャストされているので、あなたがあなたの対等にやっていることを行うことができない理由があります。これがRationalNではないクラスに対して行われると、ClassCastExceptionが発生します。

すべてのクラスがNumberを継承し、doubleValue()がNumberで使用できるメソッドとして宣言されているため、これらのクラスをNumber(Numberのインスタンスである場合)にキャストしてそこからメソッドにアクセスできるようになりました。

これは意味があると思います。私は、あなたがインターフェイスと多型について読むことをお勧めします。

編集:Numberを拡張する必要がない場合は、抽象メソッドdoubleValue()を持つ抽象クラスを作成できます。次に、equals(上記で示した)の具体的な実装を抽象クラス。次に、5つのクラスのすべてを抽象クラスに拡張します。彼らはdoubleValue()の独自のバージョンを実装しますが、抽象クラスで定義されているequals()を共有し、equals()の5つのクラスすべてへのコピー/ペーストを排除します。 Numberを拡張する必要がない場合、これは理想的なルートになります。

+0

私はこれが好きですが、この割り当ての目的でインターフェイスを利用することは許可されていません。ありがとう! –

関連する問題