오리 유형 언어에서 일반적으로 사용되는 것과 같이 물체를 스스로 검사 할 수있는 언어에서는 Liskov 대체 원칙을 볼 수 없다는 것을 올바르게 알고 있습니까?
예를 들어, 루비, 만약 클래스 B
클래스에서 상속 A
, 다음에 대한 모든 객체 x
의 A
, x.class
반환에 가고 A
있지만, 경우 x
의 목적은 B
, x.class
반환하지 않을 A
.
다음은 LSP에 대한 설명입니다.
하자 Q (x는) 개체에 대한 속성 증명할 수 X 타입의 T . 이어서 Q (y)는 물체에 대해 증명되어야 Y 타입이 S 여기서 S는 의 하위 유형 T .
예를 들어 루비에서는
class T; end
class S < T; end
속성 q (x) 에서 알 수 있듯이이 형식으로 LSP를 위반 한 경우 =x.class.name == 'T'
부가. 대답이 "예"인 경우 (LSP는 내부 검사와 호환되지 않음) 다른 질문은 다음과 같습니다. 일부 추가 조건 하에서 특수 유형 만있는 동적 언어를 보유 할 수있는 수정 된 "약한"LSP 형식이 있습니까? 의 속성 .
최신 정보. 참고로 웹에서 찾은 LSP의 또 다른 공식은 다음과 같습니다.
기본 클래스에 대한 포인터 또는 참조를 사용하는 함수는 몰래 파생 클래스의 객체를 사용할 수 있어야합니다.
그리고 또 다른:
S가 T의 선언 된 하위 유형 인 경우 S 유형의 객체는 T 유형의 객체로 취급되는 경우 T 유형의 객체가 동작 할 것으로 예상되어야합니다.
마지막으로 주석이 달립니다 :
LSP는 객체의 예상되는 동작에 관한 것입니다. 객체의 예상되는 동작이 무엇인지 분명한 경우에만 LSP를 따를 수 있습니다.
이것은 원래 것보다 약한 것으로 보이며 가능할 수도 있지만, 공식화 된 것으로보고 싶습니다. 특히 누가 예상되는 행동을 결정하는지 설명했습니다.
그렇다면 LSP는 프로그래밍 언어에서 한 쌍의 클래스의 속성이 아니라, 조상 클래스가 만족하는 주어진 속성 세트와 함께 한 쌍의 클래스의 속성입니까? 실제로 이것은 LSP와 관련하여 서브 클래스 (하위 클래스)를 구성하기 위해 조상 클래스의 모든 가능한 용도를 알아야한다는 것을 의미합니까? LSP에 따르면, 조상 클래스는 자손 클래스로 대체 가능해야합니까?
최신 정보. 나는 이미 대답을 받아 들였지만 질문을 설명하기 위해 Ruby의 구체적인 예를 하나 더 추가하고 싶습니다. 루비에서 각 클래스는 Class
클래스가 클래스의 자손 이라는 의미에서 모듈입니다 Module
. 하나:
class C; end
C.is_a?(Module) # => true
C.class # => Class
Class.superclass # => Module
module M; end
M.class # => Module
o = Object.new
o.extend(M) # ok
o.extend(C) # => TypeError: wrong argument type Class (expected Module)