2013-06-14 13 views
14

Mi piacerebbe avere un metodo compareTo che prende un Real (una classe per lavorare con numeri reali arbitrariamente grandi e precisi [beh, finché è inferiore a 2^31 di lunghezza al momento]) e un metodo compareTo che accetta un oggetto, ma Java non mi lascia e io non sono abbastanza esperto per sapere perché.Implementazione paragonabile, confronta Scontro nome: "hanno la stessa cancellazione, ma nessuno dei due sostituisce l'altro"

Ho appena provato a modificare la classe per implementare Comparable e ho ricevuto questi messaggi di errore qui sotto. Non capisco davvero cosa significano i messaggi di errore, ma so che ha qualcosa a che fare con il modo orribile in cui sto cercando di dare alla classe una certa flessibilità con tutte le diverse firme dei metodi per ogni singolo metodo che creo, e posso risolvere rimuovendo il metodo compareTo (Object other), ma preferirei tenerlo. Quindi quello che sto veramente chiedendo è: c'è un modo per far sparire questi messaggi di errore senza rimuovere il metodo compareTo (Object other) e cosa significano esattamente questi errori?

Inoltre, so che ci sono già alcune classi Java integrate come BigInteger e cose del genere per quello che sto cercando di usare questa classe, ma lo sto facendo per divertimento/soddisfazione per l'uso con Project Euler (https://projecteuler.net/).

[email protected] /cygdrive/c/Users/Jake/Documents/Java/Mathematics 
$ javac Real.java 
Real.java:377: error: name clash: compareTo(Real) in Real overrides a method whose erasure is the same as another method, yet neither overrides the other 
    public int compareTo(Real other) 
      ^
    first method: compareTo(Object) in Real 
    second method: compareTo(T) in Comparable 
    where T is a type-variable: 
    T extends Object declared in interface Comparable 
Real.java:440: error: name clash: compareTo(Object) in Real and compareTo(T) in Comparable have the same erasure, yet neither overrides the other 
    public int compareTo(Object other) 
      ^
    where T is a type-variable: 
    T extends Object declared in interface Comparable 
2 errors 

Questi sono i metodi CompareTo:

@Override 
    public int compareTo(Real other) 
    { 
    // Logic. 
    } 
    public int compareTo(char givenValue) 
    { return compareTo(new Real(givenValue)); } 
    public int compareTo(char[] givenValue) 
    { return compareTo(new Real(givenValue)); } 
    public int compareTo(char[] givenValue, int offset, int count) 
    { return compareTo(new Real(givenValue, offset, count)); } 
    public int compareTo(double givenValue) 
    { return compareTo(new Real(givenValue)); } 
    public int compareTo(float givenValue) 
    { return compareTo(new Real(givenValue)); } 
    public int compareTo(int givenValue) 
    { return compareTo(new Real(givenValue)); } 
    public int compareTo(long givenValue) 
    { return compareTo(new Real(givenValue)); } 
    public int compareTo(Object other) 
    { return compareTo(new Real(other.toString())); } 

e costruttori nel caso in cui ne avete bisogno:

public Real(String givenValue) 
    { 
    // Logic. 
    } 
    public Real(char givenValue) 
    { this(String.valueOf(givenValue)); } 
    public Real(char[] givenValue) 
    { this(String.valueOf(givenValue)); } 
    public Real(char[] givenValue, int offset, int count) 
    { this(String.valueOf(givenValue, offset, count)); } 
    public Real(double givenValue) 
    { this(String.valueOf(givenValue)); } 
    public Real(float givenValue) 
    { this(String.valueOf(givenValue)); } 
    public Real(int givenValue) 
    { this(String.valueOf(givenValue)); } 
    public Real(long givenValue) 
    { this(String.valueOf(givenValue)); } 
    public Real(Object other) 
    { this(other.toString()); } 
+0

Può noi tutta la classe mostrare? –

risposta

14

I metodi incriminati sono:

@Override 
public int compareTo(Real other) { ... } 

public int compareTo(Object other) { ... } 

Questi i metodi hanno lo stesso erasure, il che significa che una volta che il compilatore rimuove le informazioni di tipo generico, non ci sarà più un modo per differenziarle in fase di esecuzione.

Le opzioni disponibili sono per rimuovere il sovraccarico compareTo(Object other) o per Real per implementare Comparable<Object>.

Dal momento che sembra che le implementazioni di tutti i vostri compareTo sovraccarichi solo un'istanza di una nuova Real e passarlo a compareTo(Real), suggerirei loro rimozione e lasciando che la conversione fino al chiamante:

Real real = ...; 
Object compared = ...; 

Real comparedAsReal = new Real(compared); 
int result = real.compareTo(comparedAsReal); 
1

Questo è un effetto collaterale di Generics Java erosione del tipo.

si implementa un'interfaccia generica , paragonabile, ma questo suo metodo unico, una volta di tipo generico cancellato diventerà compareTo (Object), da qui si scontra con il proprio compareTo (Object).

Ecco un codice minimo per riprodurre:

class Real implements Comparable<Real> 
{ 
    public int compareTo(Object o) 
    { 
     return 0; 
    } 

    @Override 
    public int compareTo(Real o) 
    { 
     return 0; 
    }  
} 
3

Dal momento che si vuole essere in grado di confrontare Real oggetto da Object, si può solo sostituire il implements Comparable<Real> con implements Comparable<Object>. Questo sarebbe coerente con Comparable<T> javadoc che dice che <T> the type of objects that this object may be compared to.

Allora non resta che modificare il codice corrente:

// No more @Override 
public int compareToReal(Real other) 
{ 
    // Logic. 
} 
public int compareTo(char givenValue) 
{ return compareToReal(new Real(givenValue)); } 
public int compareTo(char[] givenValue) 
{ return compareToReal(new Real(givenValue)); } 
public int compareTo(char[] givenValue, int offset, int count) 
{ return compareToReal(new Real(givenValue, offset, count)); } 
public int compareTo(double givenValue) 
{ return compareToReal(new Real(givenValue)); } 
public int compareTo(float givenValue) 
{ return compareToReal(new Real(givenValue)); } 
public int compareTo(int givenValue) 
{ return compareToReal(new Real(givenValue)); } 
public int compareTo(long givenValue) 
{ return compareToReal(new Real(givenValue)); } 
@Override 
public int compareTo(Object other) 
{ return compareToReal(new Real(other.toString())); } 
Problemi correlati