6

私はオブジェクト指向プログラミング言語のクラスのいくつかのスライドを読んでいて、タイプ-サブタイプの定義に足を踏み入れました:

Barbara Liskov、「データの抽象化と階層」、SIGPLAN Notices、23、5(1988年5月):

ここで必要なのは、次の置換プロパティのようなものです。タイプSのオブジェクトo_sごとに、タイプTのオブジェクトo_Tがあり
、Tに関して定義されたすべてのプログラムPに対して、o_Sが置換されてもPの動作は変わりません。 o_Tの場合、SはTのサブタイプです

次に、例を示します。

Point = {x:Integer、y:Integer}
PositivePoint = {x:Positive、y:Positive}
ここで、Positive = {k:Integer | k>0}

PositivePoint≤Pointと言えますか?

はい。PositivePointタイプの要素は、Point用語で定義されたプログラムのPointタイプの要素を常に置き換える可能性があるためです。

さて...私にとっては、まったく逆のはずです。負の座標を持つPointを使用するプログラムではPositivePointを使用できなかったのに対し、Point≤PositivePointは逆にできたためです。

構文がまたはであるかどうかは疑問でしType ≤ Sub-typeSub-Type ≤ Typeが、ステートメントはより明確に見えます。それでは、何が問題になっていますか?


編集

物事を簡単にするために、質問は次のとおりです。それPositivePointはのサブタイプであると言えPointますか?なんで?


2回目の編集

私がコメントに書いたことをここに報告します。それが私の問題をより明確にすることを願っています。

プログラムがPoint(-100、-100)からPoint(100、100)までの正方形のマップを描画する必要があるとします。タイプを使用するとどうなります PositivePointか?プログラムの動作は変わりませんか?そうではありません。この「変わらない振る舞い」は私が得られない唯一のものです。サブタイプの定義が単にinheriting and overriding他のタイプからのものである場合、それは問題ありませんが、そうではないようです。

4

4 に答える 4

3

リスコフは正しいです。PositivePointはPointの改良版であるため、PositivePoint≤Pointです。とにかくPointの座標が正である可能性が常にあったため、Pointを使用するコードはすべてPositivePointも使用できる必要があります。逆は当てはまりません。PositivePointを使用するコードは、座標が常に正であるという仮定の下で動作する可能性があり、PositivePointをPointに置き換えるとその仮定が破られるためです。

彼女は、PositivePointがPointを置き換えることができると言っているのではなく、Pointが必要な場所でPositivePointを使用できると言っていることに注意してください。

于 2010-02-15T18:27:04.237 に答える
1

サブセットを介して型の関係をモデル化できます。

PositivePoint ⊂ Point同じ理由で成り立ちますPositiveInt ⊂ Int:正の数はすべての可能な数のサブセットです!

すべてがsにPositivePoint属しますが、そのPoint逆ではありません。

于 2010-02-15T18:27:12.713 に答える
1

アイデアは、PositivePointを受け入れる関数は、ポイントの値が正であるという事実に依存しているということです。値が正ではないポイントを渡した場合、仮定は偽であり、関数は失敗します。

ただし、ポイントを受け入れる関数は、ポイントの正の値を想定しないため、PositivePointを渡した場合は問題ありません。

これは、不変のPointクラスにのみ当てはまることに注意してください。p.x = -1ポイントの値を変更できた場合、PositivePointの操作は失敗するため、PositivePointとPointはサブクラスの関係にまったくない可能性があります。

編集:詳しく説明するには:

必要に応じて自動的に大きくなる2次元配列があるとします(つまり、2つの正のインデックスを渡すときにインデックスの範囲外エラーが発生することはありません)。これで、PositiveInteger pを受け取り、インデックスx、yの2次元配列にアクセスする関数ができました。xとyは正であることが保証されており、2d配列は正のインデックスの任意のペアでインデックス付けできるため、これは失敗することはありません。ただし、PointがPositivePointのサブタイプである場合、pは正であると宣言されていても、実際には負の値になる可能性があります。これは、配列のインデックス作成に使用するのが安全ではなくなったことを意味します。

ただし、ポイントを受け入れる関数は、ポイントの値が負であるか正であるかを認識していません。すでに、それらが正である可能性を考慮に入れる必要があります。したがって、PositiveIntegerを渡すことは何も壊すことはできません。

于 2010-02-15T18:28:55.817 に答える
0

これを表すために使用される≤記号はこれまで見たことがありませんが、潜在的な値の範囲がより広いPositivePoint ≤ Pointことを意味すると思います(つまり、のサブセットであり、のすべてのインスタンスをの有効なインスタンスに置き換えることができます、ただしその逆ではありません。)PointPositivePointPositivePointPointPositivePointPoint

于 2010-02-15T18:24:55.420 に答える