Sto programmando in Java e ho il seguente problema:
Mi piacerebbe fare il rilevamento delle collisioni. Per questo, ho bisogno di diversi tipi di BoundingBox
es. Per esempio, diciamo che ho entità che hanno una scatola di collisione circolare e entità che hanno un rettangolo di delimitazione. Quindi ho bisogno di due classi, BoundingBoxCircle
e BoundingBoxRectangle
per implementare il rilevamento delle collisioni. Inoltre, mi piacerebbe avere una classe astratta BoundingBox
che ha il metodo astratto collidesWith(...)
, che prende come argomento un qualche tipo di BoundingBox
e restituisce se è attualmente in collisione con qualche altro BoundingBox
.
Ora per il problema: non riesco a trovare un buon modo per strutturarlo a livello di programmazione. Essenzialmente, ho bisogno di implementare diversi rilevamenti di collisione tra rettangoli e cerchi (e potenzialmente altre forme). Mi piacerebbe anche essere in grado di chiamare questi metodi "bene". Quando ho un determinato riquadro di delimitazione, ad esempio BoundingBoxCircle
, vorrei poter chiamare boundingBoxCircle.collidesWith(rectangle)
e inviarlo dinamicamente al metodo che gestisce il rilevamento delle collisioni rettangolo-cerchio. Tuttavia, questo non funziona:
public abstract class BoundingBox {
public abstract boolean collidesWith(BoundingBox b);
}
public class BoundingBoxCircle {
@Override
public boolean collidesWith(BoundingBoxRectangle b) {
...
}
}
Perché la firma del metodo sovrascritto non è la stessa.
Quindi posso pensare a due opzioni:
- Fornisci tutte le firme dei metodi nella superclasse
- Sostituisci
collidesWith
in tutte le sottoclassi
Il primo ha il problema che dovrei fornire le firme circleCollidesWithRectangle
, rectangleCollidesWithCircle
(ecc.) nella classe BoundingBox
, che è abbastanza brutta, perché essenzialmente ho "informazioni" in BoundingBox
che dovrebbe davvero essere parte delle sue sottoclassi.
Il secondo ha il problema che avrei bisogno di sovrascrivere il metodo collidesWith(BoundingBox b)
in ogni sottoclasse, il che significa che non so quale tipo b
sia - quindi dovrei controllare tutti i casi in ogni sottoclasse; in sostanza:
class BoundingBoxRectangle extends BoundingBox {
@Override
public boolean collidesWith(BoundingBox b) {
if (b typeof BoundingBoxRectangle) {
...
} else if (b typeof BoundingBoxCirce) {
...
} else {
throw new IllegalStateException("unexpected type");
}
}
}
... che potrebbe portare a una quantità folle di dichiarazioni if se inizi a programmare più sottoclassi per BoundingBox
. Ha anche lo svantaggio che potrei dimenticare di aggiungere un'istruzione if in futuro, che è potenzialmente difficile da trovare, perché lancio solo un'eccezione se la collisione viene controllata per due entità specifiche.
Mi piacerebbe davvero implementarlo in un modo che mi permette di vedere i metodi mancanti in fase di compilazione e non richiede la ripetizione del codice.