My specific case is this:

I have an abstract superclass: GravitationalBody.

From it is derived other classes, notably: Planet; Shot; and Ship.

GravitationalBody has a field, an ArrayList<GravitationalBody> that contains references to every instance of a subclass: This is because there are static methods in GravitationalBody that loop every game round to adjust the position, velocity, acceleration, etc of every single "Gravitational Body" in the game.

There is another static method in there that detects for collisions between any of the aforementioned subclasses. To do this, it takes every object out from the collection and tests for an Area overlap with the rest of the objects. (Overwhelmingly resource consuming at the moment, but not my current worry)

Once it detects a collision, however, I am unsure how to enable specific reactions BETWEEN the subclasses. Right now, one body is dubbed "self" and the other is "other," and the code after a collision is detected is:

However, because self and other have both just been taken out of the ArrayList, they are determined to be of the type GravitationalBody.

But, I want each subclass to have particular interactions with the other subclasses! For example, a planet colliding with a planet will react differently than a shot colliding with a planet. But how do I properly override and overload these methods? Each subclass right now has the collidedWith() method overridden and overloaded for things such as:
collidedWith(Planet planet)
collidedWith(Ship ship)
collidedWith(Shot shot)

The easy way out is obviously to use instanceof, but I would much rather know the classy way of fixing this problem. Is it a flaw in my design or is there a valuable tool out there?