2013-06-14 30 views
14

Chciałbym mieć metodę compareTo, która pobiera Real (klasa do pracy z dowolnie dużymi i precyzyjnymi liczbami rzeczywistymi [dobrze, o ile w tym momencie jest mniej niż 2^31) i metoda compareTo, która przyjmuje obiekt, ale Java nie pozwala mi, a ja nie jestem wystarczająco doświadczony, aby wiedzieć, dlaczego.Wdrażanie Porównywalne, porównawcze zderzenie nazw: "mają to samo wymazanie, ale żaden nie zastępuje innego"

Po prostu próbowałem zmodyfikować klasę, aby zaimplementować Porównywalne i dostałem te komunikaty o błędach poniżej. Naprawdę nie rozumiem, co oznaczają komunikaty o błędach, ale wiem, że ma to coś wspólnego z okropnym sposobem, w jaki próbuję nadać klasie pewną elastyczność z różnymi sygnaturami metod dla każdej tworzonej przeze mnie metody, i mogę naprawić poprzez usunięcie metody compareTo (Object other), ale najlepiej byłoby ją zachować. Tak naprawdę pytam: Czy istnieje sposób, aby te komunikaty o błędach zniknęły bez usuwania metody compareTo (Object other) i co dokładnie oznaczają te błędy?

Ponadto wiem, że istnieją już wbudowane klasy Java, takie jak BigInteger i podobne rzeczy, dla których próbuję korzystać z tej klasy, ale robię to dla zabawy/satysfakcji do użycia z 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 

Są to metody 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())); } 

i konstruktorzy tylko w przypadku trzeba je:

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

Może pokażesz nam cała klasa? –

Odpowiedz

14

Metody obrażając to:

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

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

These metody mają ten sam erasure, co oznacza, że ​​gdy kompilator usunie ogólne informacje o typie, nie będzie już sposobu na ich odróżnienie w czasie wykonywania.

Dostępne opcje to usunięcie przeciążenia compareTo(Object other) lub Real w celu wykonania Comparable<Object>.

Ponieważ wygląda na implementacje wszystkich compareTo przeciążeń tylko wystąpienie nowego Real i przekazać go do compareTo(Real), polecam ich usunięcie i pozostawienie takiej konwersji do rozmówcy:

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

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

To jest efekt uboczny z Java generics type-erasure.

Jesteś wdrożenie rodzajowy interfejs, porównywalne, ale to jego unikalna metoda, gdy typ rodzajowy usunięte zostanie compareTo (Object), stąd też starcia z własnym compareTo (Object).

Oto minimalny kod do odtworzenia:

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

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

Ponieważ chcesz, aby móc porównać Real obiekt do Object, można po prostu zastąpić implements Comparable<Real> z implements Comparable<Object>. Byłoby to zgodne z Comparable<T> javadoc, który mówi, że <T> the type of objects that this object may be compared to.

Wtedy po prostu trzeba zmienić aktualny kod do:

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