6

Square を Rectangle クラスの継承クラスにすることは悪い習慣であり、LSP (Liskov 代替原理) に違反しているとの記事を読んだことがあります。まだわかりません。Ruby でサンプル コードを作成しました。

class Rectangle
    attr_accessor :width, :height
    def initialize(width, height)
        @width = width
        @height = height
    end
end

class Square < Rectangle
    def initialize(length)
        super(length, length)
    end
    def width=(number)
        super(number)
        @height = number
    end

    def height=(number)
        super(number)
        @width = number
    end
end


s = Square.new(100)

s.width = 50

puts s.height

何が問題なのか誰か教えてもらえますか?

4

3 に答える 3

2

Liskov 代替原理 (LSP) の観点から見た場合の何が問題なのかは、RectangleSquareが変更可能であることです。つまり、サブクラスでセッターを明示的に再実装する必要があり、継承の利点が失われます。s を不変にする場合Rectangle、つまり、別のものが必要なRectangle場合は、既存の測定値を変更するのではなく、新しいものを作成する場合、LSP に違反しても問題はありません。

class Rectangle
  attr_reader :width, :height

  def initialize(width, height)
    @width = width
    @height = height
  end

  def area
    @width * @height
  end
end

class Square < Rectangle
  def initialize(length)
    super(length, length)
  end
end

を使用attr_readerするとゲッターは提供されますが、セッターは提供されないため、不変性になります。この実装では、 と の両方がRectanglesSquaresに可視性を提供しますheightwidth正方形の場合、それらは常に同じになり、面積の概念は一貫しています。

于 2013-05-29T04:17:22.147 に答える
0

抽象基本クラスまたはインターフェースを検討してください (何かがインターフェースであるか抽象クラスであるかは、LSP とは関係のない実装の詳細です) ReadableRectangle。読み取り専用のプロパティWidthHeight. そこから type を派生させることは可能ですがReadableSquare、これは同じプロパティを持ちますが、契約上は常に等しいことをWidth保証します。Height

からReadableRectangle、具象型ImmutableRectangle(コンストラクターで高さと幅を受け取り、HeightWidthプロパティが常に同じ値を返すことを保証する) とMutableRectangle. MutableRectangle高さと幅をいつでも設定できる具象型を定義することもできます。

物事の「正方形」側では、 anは anと aImmutableSquareの両方に置き換え可能であるべきです。ただし、 aは a にのみ代入可能です[これは a に代用可能です。] さらに、 an の動作は anに代用可能ですが、具象型を継承することによって得られる値は制限されます。抽象型またはインターフェイスの場合、クラスはその次元を保持するために 2 つではなく 1 つのフィールドを使用するだけで済みます (2 つのフィールドを持つクラスの場合、1 つを節約することは大したことではありませんが、より多くのフィールドを持つクラスを想像するのは難しくありません)大幅な節約が可能な分野)。ただし、が具象型の場合、どの派生型もそのベースのすべてのフィールドを持つ必要があります。ImmutableRectangleReadableSquareMutableSquareReadableSquareReadableRectangleImmutableSquareImmutableRectangleImmutableRectangleImmutableRectangleImmutableSquareImmutableRectangle

一部のタイプの正方形は、対応するタイプの長方形の代わりに使用できますが、変更可能な正方形は変更可能な長方形の代わりに使用できません。

于 2013-07-02T22:15:32.983 に答える