[ 클래스 설계 ]
open class Rectangle {
open var width : Int = 1
open var height : Int = 1
}
class square : Rectangle () {
override var width : Int = super.width
get() = super.width
set(value) {
field = value
height = value
}
override var height : Int = super.height
get() = super.height
set(value) {
field = value
width = value
}
}
fun increaseHeight(rec : Retangle) {
if(rec.height <= rec.width) {
rec.height = rec.width + 10
}
}
위 함수를 Rectangle의 하위클래스인 square 클래스 객체가 사용한다면 높이가 더 길어지지 않는다. 이는 IncreaseHeight()함수가 Rectangle의 확장에 열려있지 않다는 뜻이다.
=> '정사각형은 직사각형이다.'라는 명제가 성립하지만, 프로그램을 짤 때 'square 객체는 Rectangle 객체이다.'로 설계하는 것은 문제가 있다.
다형성에서 하위클래스는 인터페이스 규약을 다 지켜야한다.
(예시) 자동차 인터페이스의 엑셀은 앞으로 가라는 기능이 있는데 갑자기 뒤로가게 한다면 LSP 위반이다. 느리더라도 앞으로 가야 LSP에 위반되지 않는다.
🪐 하위 타입을 정의할 때는 상위 타입의 명세를 지켜야 LSP를 지킬 수 있다. 따라서 상위 타입에 명세를 명확하게 잘 기록해야한다.
🪐 DownCasting을 사용하면 OCP를 위반하기도 하지만, LSP를 위반하기도 한다.상위 타입 객체를 하위 타입의 객체로 바꿨을 때 모든 하위 타입에 대해 잘 동작하지 않을 가능성이 크기 때문이다. 상위 타입의 객체가 하위타입인지 확인하는 코드를 사용하는 것은 상위 클래스가 제대로 추상화 되지 않았다는 것을 의미한다.
참고한 블로그