2011-12-22 13 views
1

私はアイテムのリストを宣言するモデル抽象クラスを持っています。抽象クラスには2つの抽象クラスがあります。リストに新しい項目を追加することができ、リストをまったく使用しない項目を追加することができますが、そうでなければモデル抽象クラスの他の動作に従います。この場合、LSP(Liskov置換)に違反することはできますか?

リストに項目を追加したり削除したりする2つの方法を宣言しました。明らかに、私がそれらのメソッドを使用したいときは、モデル抽象クラスをそのサブクラスにキャストする必要があります。

この場合、LSP (Liskov substitution principle)に違反することはできますか?または、この問題を回避する方法はありますか?

+6

いくつかのコードを表示してください。それははるかに明確になります。 –

+0

クラスの継承はここに行く方法ではないようです。継承は、基本クラスを透過的に派生クラスに置き換えることができれば、ほとんどの場合理にかなっています。 – helpermethod

+0

Liskovの置換原則に違反することはほとんど決して良い考えではないので、これを正当化するためには本当に強い議論が必要です。 – Jesper

答えて

1

私はあなたがLSPに違反すると思います。 Wikipedia page for LSPから

(それは常にあなたの友達です;):

「より正式に、リスコフの置換原則(LSP)は(強い)行動のサブタイプと呼ばれるサブタイプ関係の特定の定義は、あります」

は「行動サブタイプは、引数の型と戻り値の型の共分散のcontravarianceにのみ依存型理論、で定義された関数の典型的なサブタイプよりも強いという概念である。行動サブタイプは、一般的には自明決定不能である」

あなたのケースのようになり:

「LSPに違反する典型的な例は、ゲッターとセッターメソッドは、幅と高さの両方に存在すると仮定すると、Rectangleクラスから派生スクエアクラスです。 Squareクラスは、常に幅が高さと等しいことを前提としています。 Rectangleが予想されるコンテキストでSquareオブジェクトが使用されている場合、Squareのディメンションが独立して変更できない(またはそうではない)ため、予期しない動作が発生する可能性があります。この問題は簡単には解決できません:Rectクラスのセッターメソッドを変更してSquare不変式を保持する(つまり、次元を同じに保つ)と、これらのメソッドはRectangleセッターの事後条件を弱める(違反する)でしょう。寸法は独立して変更できることを述べている。 LSPの違反は、このように、または練習」私はLSPを理解

0

LSPを研究していないが、病気にキャストする必要がこの

は常に悪い(少ない最適な)オブジェクト指向設計の兆候であると言うん。あなたはあなたがあまりにも物事を設定することができますモデルは

同じ正しいモデルとしてそれを宣言したい場合は

のJavaコレクションAPIのために行く

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

は動作しますが、ちょうどひどく書かれたコードです

はoffcourse

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

使用されている必要がありますあなたが望むものの特定のタイプ

0

で問題であってもなくてもよいが、ここではこの問題は、Javaは、単一継承と複数のインタフェースを持っていることを、設計理由に対処していることかもしれません。

1つのクラスで他のクラスを1つだけ拡張できます。C++では、これは当てはまらず、スーパークラスには矛盾する名前が存在する可能性があります。多重継承は、理論的なタイプの問題もいくつか示しました。

したがって、1つのアスペクトをインターフェイスに変換し、1つまたは複数のインターフェイスを実装する抽象クラスから拡張する必要があります。

SquareがRectangleから拡張し、WidthEqualsHeightを実装する場合、LSPが保持します。

関連する問題