1

アイテムのリストを宣言するモデル抽象クラスがあります。抽象には2つの抽象クラスがあります。リストに新しいアイテムを追加できるものと、リストをまったく使用しないが、それ以外の場合はモデル抽象クラスの他の動作に準拠するもの。

リストからアイテムを追加および削除する2つのメソッドを宣言しました。明らかに、これらのメソッドを使用するときはいつでも、モデル抽象をそのサブクラスでキャストする必要があります。

この場合、 LSP(リスコフの置換原則)に違反することはできますか?または、この問題を回避する方法はありますか?

4

3 に答える 3

1

LSPに違反すると思います。

LSPのウィキペディアページから(それは常にあなたの友達です;):

「より正式には、リスコフの置換原則(LSP)は、(強力な)振る舞いサブタイピングと呼ばれるサブタイピング関係の特定の定義です。」

「振る舞いサブタイピングは、型理論で定義された関数の典型的なサブタイピングよりも強力な概念です。これは、引数タイプの反変性と戻り型の共分散のみに依存します。振る舞いサブタイピングは、一般に簡単に決定できません。」

あなたの場合に似ています:

「LSPに違反する典型的な例は、Rectangleクラスから派生したSquareクラスで、幅と高さの両方にgetterメソッドとsetterメソッドが存在すると想定しています。Squareクラスは、常に幅が高さと等しいと想定しています。Squareオブジェクトが使用されている場合Rectangleが予想される状況では、Squareのディメンションを個別に変更できない(または変更すべきではない)ため、予期しない動作が発生する可能性があります。この問題は簡単に修正できません。Squareクラスのsetterメソッドを次のように変更できる場合それらはSquare不変を保持し(つまり、次元を等しく保つ)、これらのメソッドは、次元を個別に変更できることを示すRectangleセッターの事後条件を弱めます(違反します)。このようなLSPの違反は、そうでない場合もあります。実際に問題になる」

于 2011-12-22T10:45:21.753 に答える
0

LSPを勉強したことはありませんが、これは悪いことです

キャストしなければならないことは、常に悪い(最適ではない)OOデザインの兆候です。

設定もできるモデルが必要な場合は、正しいモデルとして宣言してください

JavaコレクションAPIについても同じことが言えます

Collection coll = new ArrayList();
((List) coll).set(3,"sdf");

動作するコードですが、ひどく書かれています

オフコースがあったはずです

List coll = new ArrayList();
coll.set(3,"sdf");

あなたが望むもののために特定のタイプを使用してください

于 2011-12-22T10:39:04.437 に答える
0

私はLSPを理解していますが、ここでは、Javaが単一の継承と複数のインターフェースを持っているという設計上の理由に問題が対処している可能性があります。

1つのクラスで他の1つのクラスを拡張できます。C ++ではそうではなく、スーパークラスで名前が競合する可能性があります。多重継承は、いくつかの理論的な型の問題ももたらしました。

したがって、1つの側面をインターフェースに変換し、1つ以上のインターフェースを実装する抽象クラスから拡張する必要があります。

LSPは、SquareがRectangleから拡張され、WidthEqualsHeightを実装するときに保持されます。

于 2011-12-22T10:53:06.307 に答える