2012-08-30 22 views
5

Powiel możliwe:
Returning false from Equals methods without Overridingrówna return false

Jeden mój kolega zadał mi pytanie dzisiaj jak wspomniano poniżej

TestEquals zapisu klasy (na zamówienie lub zdefiniowane przez użytkownika klasy) tak, że poniższy kod w kodzie wypisze false.

public class Puzzle3 { 
    public static void main(String[] args) { 
    TestEquals testEquals = new TestEquals(); 
    System.out.println(testEquals.equals(testEquals)); 
    } 
} 

Uwaga: Nie można przesłonić równa się metody.

Dużo myślałem, ale nie mogłem znaleźć rozwiązania bez przesłonięcia równości. Czy ktoś ma pojęcie, jak to zrobić?

+7

To nie jest praca domowa? –

+4

Czy ** przeciążenie ** jest dozwolone? – home

+2

Duplikat dostał dwie notatki w dół, a zaakceptowana odpowiedź tylko cztery awanse. Co tym razem sprawia, że ​​pytanie jest o wiele lepsze? – maba

Odpowiedz

17

użycie

public boolean equals(TestEquals equals) { 
    return false 
} 

Aby przesłonić równa trzeba parametru wejściowego być typu obiektu więc powyższy fragment kodu theorectially nie jest nadrzędnym równa z metody obiektu

+5

Może również zwrócić "String", jeśli masz na to ochotę. –

+0

Niesamowite! Do tej pory 13 przegranych. – maba

+0

@DuncanJones dobry punkt Nie wymyśliłem tego +1 za wskazanie, że na zewnątrz – RNJ

0

nie wiem dlaczego miałby każdy chce to zrobić. Ale można utworzyć metody, jak pokazano poniżej:

public boolean equals(SuperEquals equals) { return false; } 

Gdzie SuperEquals jakakolwiek nadklasą TestEquals ale nie Object.

1

Jak wspomniano powyżej, można napisać metodę tak:

public boolean equals(TestEquals e) { 
    return false; 
} 

Ponadto, jeśli TestEquals może przedłużyć jakiś inny obiekt:

public TestEquals extends Something { 
} 

public Something { 
    @Override public boolean equals(Object o) { 
     return false; 
    } 
} 
11

EDIT: Najwyraźniej someone else przybył na ten pomysł pierwszy w innym wątku, ale zostawię to tutaj, ponieważ ten kod jest znacznie prostszy.


class TestEquals { 

    static { 
    System.setOut(new PrintStream(new FilterOutputStream(System.out) { 
     public void write(byte[] buf, int pos, int len) throws IOException { 
     if (len >= 4 && buf[pos] == 't') { 
      out.write(new byte[] { 
       (byte) 'f', (byte) 'a', (byte) 'l', (byte) 's', (byte) 'e' 
      }); 
      out.write(buf, pos + 4, len - 4); 
     } else { 
      out.write(buf, pos, len); 
     } 
     } 
    })); 
    } 
} 

To straszne siekać nie zastępują lub przeciążenie nic wspólnego z equals, ale sam akt tworzenia instancji TestEquals powoduje klasę obciążenia, które otacza System.out tak, że każda kolejna druku, który zaczyna się 't' spowoduje wydrukowanie "false" zamiast pierwszych 4 bajtów. (Zakładając, że kodowanie domyślne nie jest czymś super-egzotycznym.)

+0

Doskonały pomysł :) – gontard

+0

+1 za myślenie po wyjęciu z pudełka. – maba

-1

Na moim iPadzie ... Strategia powinna być czymś podobnym do posiadania atrybutu aun, który jest modyfikowany za każdym razem, gdy robisz z niego użytek .. to zadziała, jeśli atrybut jest dostępny przez getter na równych. Wspomniałeś, że równe wartości nie mogą być przesłonięte, więc atrybut powinien być prywatny, a modyfikacja wartości ma miejsce przed odczytem wartości i po niej, aby upewnić się, że działa niezależnie od tego, czy jest to pierwsza czy druga część równa.

Coś jak (przepraszam za ewentualne błędy składniowe):

public class TestEquals{ 

private int id; 

public int getId(){ 
    int temp; 
    id++; 
    temp=id; 
    id++; 
    return temp; 
} 
} 
+0

Pierwsza kontrola w Object.equals (Object obj) to 'if (this == obj) return true'. –

Powiązane problemy