最も近い点を使用して 2 つのオブジェクト間の距離を計算するメソッドを実装している場合、両方のオブジェクトの型を知る必要があるため、これは難しい問題です。たとえば中心点を使用して比較する場合は簡単です。GetCenter
メソッドを追加するだけですが、この場合はうまくいきません。
問題は、クラス階層を拡張可能に設計できる場合 (つまり、既存の型を変更せずに他の型を追加できる場合) にクラス階層が役立つことです。追加するときに、 などEllipse
を実装する必要があるため、これはここでは当てはまりません...関数型言語で知られている代数データ型を使用してこれを表現する方がはるかに簡単です。たとえば、F# では次のようになります。DistancePointEllipse
DistanceTriangleEllipse
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
関数型プログラミングは、この問題により適しているようです:-)。
とにかく、可能な(ただしまだ非拡張の)オブジェクト指向設計の 1 つは、現在のタイプから他のタイプの形状までの距離を計算するメソッド、などをShape
含む基本クラスを持つことです(すべての組み合わせが本当に必要なため)。 .DistanceToPoint
DistanceToTriangle
別のアプローチは、オーバーロードされたメソッドを C# で単純に記述することです。
float Distance(Triangle t, Point p);
float Distance(Triangle t, Circle c);
// ... etc
このオプションの良い点は、作成する必要があるメソッドの数を簡単に減らすことができることです。Ellipse
たとえば、とのケースがある場合、Point
を継承Circle
してEllipse
、 と比較するときに既存のケースを使用するCircle
こともできPoint
ます。