Это сложная проблема, потому что если вы реализуете метод для вычисления расстояния между двумя объектами, используя ближайшую точку, вам действительно нужно знать, какие типы оба объектов. Если бы вы сравнивали его, используя, например, центральную точку, то это было бы легко - вы просто добавили бы метод GetCenter
, но в этом случае это просто не сработало.
Проблема в том, что иерархии классов полезны, если вы можете создать их как расширяемые, то есть разрешить добавление других типов без изменения существующих. Здесь дело обстоит не так, потому что когда вы добавляете Ellipse
, вам нужно реализовать DistancePointEllipse
, DistanceTriangleEllipse
и т. Д. Было бы намного проще представить это, используя алгебраический тип данных известный из функциональных языков. Например в F #:
type Shape =
| Circle of float * float * float // center & radius
| Point of float * float // center
Тогда вы можете использовать сопоставление с образцом для обработки всех возможных случаев:
match shape1, shape2 with
| Circle(x1, y1, r1), Circle(x2, y2, r2) -> // two circles
| Point(x1, y1), Point(x2, y2) -> // two points
| Circle(cx, cy, r), Point(px, py)
| Point(px, py), Circle(cx, cy, r) ->
// point and a circle (both combinations
Функциональное программирование просто лучше подходит для этой проблемы: -).
В любом случае, один из возможных (но все еще не расширенных) объектно-ориентированных проектов будет иметь базовый класс Shape
с методами DistanceToPoint
, DistanceToTriangle
и т. Д., Которые вычисляют расстояние от текущего типа до другого. тип фигуры (так как вам действительно нужны все комбинации).
Другим подходом было бы просто написать перегруженный метод на C #:
float Distance(Triangle t, Point p);
float Distance(Triangle t, Circle c);
// ... etc
Приятной особенностью этой опции является то, что вы можете легко сократить количество методов, которые вам нужно написать. Например, если у вас есть регистр для Ellipse
и Point
, вы можете наследовать Circle
от Ellipse
, а затем использовать существующий регистр при сравнении Circle
с Point
.