3

クラスを持つと書かれている本があり、それから を継承PhoneNumberするクラスを定義します。私はかつて、アドレスは電話番号ではないため、継承することはできないと言いました。それは「である」関係でなければなりません。たとえば、犬は動物であり、から継承させることができます。AddressPhoneNumberDogAnimal

しかし、LSP -- Liskov Substitution Principleに従わなければならないので、正方形は "is a" 長方形 (幅 == 高さ) であるため、"is a" ルールは実際には決定要因ではありませんが、LSP はできると言います。クラスを定義し、そのSquareクラスから継承しRectangleます。aRect英語での簡単な説明は、オブジェクトはメッセージsetWidthAndHeight(w, h)に応答できますが、aSquare正しく応答できず、プログラム全体が正しく実行できないということだと思います。

驚くべきことに、Addressクラスを継承するPhoneNumberクラスは「is a」の関係に違反していますが、LSP には違反していません。正式には、どの OOP 原則に違反していますか?

4

2 に答える 2

1

まず、これは実際に LSP に違反しています。

通常、PhoneNumbers を Addresses で置き換えることは期待できません。それが、コメントで誰もが話している「常識」のビットです。

OOP 理論の要点は、正式なルールに従うことで、変更や奇妙なユース ケースなどに対してクラスが堅牢になるということです。本の例が実際には LSP 違反で壊れなくても、そのクラス アーキテクチャを拡張しようとするとすぐに壊れると思います。したがって、クラスの将来の潜在的なエラーを回避するには、LSP に従う必要があります。そうしないことを選択しても、すぐには何も壊れません。

第 2 に、ISP (インターフェイス分離の原則) に違反しています。

これは、クラスで使用可能なメソッドのセットが、クラスのオブジェクトが機能するために必要な最小限のものでなければならないことを示しています。

Address クラスが、実際の番地を処理する際に決して使用されない一連の PhoneNumber メソッドを継承する (または合理的に継承する可能性がある) 場合 (たとえば、家の住所では定義されない getAreaCode() メソッド)、そのインターフェースは継承されません。最小限。

これの要点は、OOP の原則は実際にはガイドラインにすぎないということです。SOLID の原則に違反しているにもかかわらず、実際にはバグを導入していない奇妙なサンプル コードを作成することは間違いなく可能です。これは、ルールを回避しているという意味ではありません。クラスを拡張しようとするとすぐに、さらに多くのバグが発生することになります。

于 2013-02-26T03:50:13.603 に答える
0

継承または拡張を使用する主な理由は 2 つあります。

  1. 再利用の実装 (DRY 用)
  2. サブタイピング (LSP 関連)

私はすべての原則を知っているわけではありませんが、@mpmがコメントしたように、あなたの場合、違反するのは常識です。

コードがすべての原則を満たしている場合でも、不適切である可能性があるためです。つまり、原則だけではすべてを網羅することはできません。

于 2013-02-25T05:19:14.137 に答える