Простой ответ - реализовать (например) метод пересечения окружности следующим образом:
public void isIntersecting(Rectangle rectangle) {
rectangle.isIntersecting(this);
}
Я не могу придумать более элегантный метод.
Проблема с определением метода API следующим образом:
public void isIntersecting(Shape) { ... }
означает, что вам приходится кодировать переключатель instanceof регистром для каждой из различных форм. Повторяющийся код все еще там, и вы заменили статическую типизацию чем-то потенциально более хрупким ...
(AFAIK, нет общего / эффективного алгоритма для проверки, если две произвольные фигуры пересекаются. Особенно, если фигуры содержат изогнутые линии.)