J. Bloch nel suo Java efficace fornisce diverse regole per l'implementazione per il metodo di uguaglianza. Eccoli:Metodo di comprensione degli uguali
• Riflessivo: Per ogni valore di riferimento non nullo x, x.equals (x) devono restituire true.
• Simmetrico: per qualsiasi valore di riferimento non nullo x e y, x.equals (y) deve restituire true se e solo se y.equals (x) restituisce true.
• transitiva: Per non nullo valori di riferimento x, y, z, se x.equals (y) restituisce true e y.equals (z) restituisce true, quindi x.equals (z) deve tornare vero.
• Coerente: Per qualsiasi riferimento non nullo valori x ed y, più invocazioni x.equals (y) costantemente ritorno vere o costantemente ritorno falso, fornito informazioni utilizzate in uguale confronto sugli oggetti viene modificato .
• Per qualsiasi valore di riferimento xnon valido, x.equals (null) deve restituire false.
Ma più tardi nel libro ha citato cosiddetto Liskov principio di sostituzione:
Il principio di sostituzione Liskov dice che qualsiasi proprietà importante di un tipo dovrebbe valere anche per i suoi sottotipi, in modo che qualsiasi metodo scritta per il tipo dovrebbe funzionare altrettanto bene sui suoi sottotipi
non vedo come si collega ai equals
contratti. Dovremmo effettivamente aderirvi mentre scriviamo l'implementazione degli uguali?
La domanda riguarda l'implementazione del metodo per le sottoclassi. Ecco l'esempio dal libro:
private static final Set<Point> unitCircle;
static {
unitCircle = new HashSet<Point>();
unitCircle.add(new Point(1, 0));
unitCircle.add(new Point(0, 1));
unitCircle.add(new Point(-1, 0));
unitCircle.add(new Point(0, -1));
}
public static boolean onUnitCircle(Point p) {
return unitCircle.contains(p);
}
public class CounterPoint extends Point {
private static final AtomicInteger counter = new AtomicInteger();
public CounterPoint(int x, int y) {
super(x, y);
counter.incrementAndGet();
}
public int numberCreated() { return counter.get(); }
}
e la seguente implementazione:
// Broken - violates Liskov substitution principle (page 40)
@Override public boolean equals(Object o) {
if (o == null || o.getClass() != getClass())
return false;
Point p = (Point) o;
return p.x == x && p.y == y;
}
Ok, viola e che cosa poi? Non capisco.
anche le superclassi non dovrebbero conoscere i suoi figli, ma l'oggetto sa che la classe stringa^^ java non è affatto ben progettata. – Zelldon
@Zelldon Si prega di elaborare, cosa intendi per "oggetto conosce stringa"? (Non sto seguendo la richiesta) – amit
L'oggetto ha il metodo 'toString()'. –