Tricky comparePer l'ereditarietà, facile da estendere - Java

5

Diciamo che abbiamo 4 classi A, B, C, D dove: A è una superclasse di entrambi B e C e C è una superclasse di D. Suppongo che, in un diagramma, dovrebbe assomigliare a questo:

   A
 /   \
B     C
       \
        D

Inoltre, la classe A implementa l'interfaccia

Comparable<A> 

e implementa anche un metodo

public int compareTo(A another)

Mi piacerebbe essere in grado di confrontare ogni coppia di oggetti x, y tale che siano istanze di classi dall'insieme {A, B, C, D}. Naturalmente, dovrei implementare un metodo compareTo in ciascuna di queste classi, ma per impostazione predefinita sto facendo questo con un effetto unilaterale, cioè definendo come confrontare l'oggetto c da C con b da B non dice nulla su come confrontare b con c. Ora, potrei scrivere un sacco di codice e gestire tutti questi casi (questo significa anche che dovrei usare il metodo 'isInstance' per gestirli, giusto?) Ma poi ogni due classi devono essere 'consapevoli dell'esistenza di altri . Quindi, se volessi aggiungere un'altra classe, E, tale che D sia una superclasse di E, dovrei servire tutti i casi nella nuova classe E e inoltre dovrei cambiare qualcosa nelle classi A, B, C, D per "essere consapevole di E".

Quindi mi sto sforzando di trovare una soluzione elegante, cioè che non implichi un cambiamento significativo aggiungendo una nuova classe alla gerarchia. Come posso ottenere questo?

Grazie in anticipo per l'aiuto.

    
posta socumbersome 03.04.2013 - 10:41
fonte

2 risposte

3

Potresti scrivere un metodo generale compareTo nella classe A , che usa una chiave calcolata da un metodo compareKey che è anche in A , ma può essere sovrascritto da ciascuna sottoclasse per fare una distinzione fine come vuole Se rendi un valore float, puoi continuare a suddividere il criterio di confronto ogni volta che viene aggiunto un nuovo livello di classi ereditanti (entro limiti ragionevoli).

    
risposta data 03.04.2013 - 10:52
fonte
1

Penso che quello che vuoi sia una sorta di dispatch multiplo che viene usato di solito in Java usando il pattern Visitor, ma dovresti cambiare il codice quando aggiungi nuove classi.

Dato che non hai davvero bisogno di una spedizione multipla completa, penso che la seguente potrebbe essere una buona soluzione. Scrivi il tuo confrontoPer metodi come questo: (Questo è quello in TestB)

@Override
public int compareTo(TestA o) {
    if(o instanceof TestB) {
        // add your code instead
        System.out.println("Compare Bs");
        return 0;
    } else {
        return super.compareTo(o);
    }
}

Poiché la chiamata a x.compareTo viene risolta in fase di esecuzione, si esegue sempre la funzione compareTo della classe più specifica. Controllando se l'altro argomento è l'istanza della classe corrente, puoi rilevare quando devi risalire la gerarchia che puoi chiamare super.compareTo.

Fammi sapere se hai altre domande. :)

Modifica: ho pensato che quello che volevi fare fosse comparare come l'antenato più specifico come da commento alla domanda originale.

    
risposta data 05.04.2013 - 10:11
fonte

Leggi altre domande sui tag