영호

[OOP] SOLID - LSP(리스코프 치환 원칙) 본문

OOP

[OOP] SOLID - LSP(리스코프 치환 원칙)

0h0 2022. 6. 5. 13:12

LSP(리스코프 치환 원칙)이란

SOLID에서 L에 해당하는 원칙으로, "상위 타입의 객체를 하위 타입의 객체로 치환을 해도 프로그램은 정상적으로 동작을 해야 한다."라는 내용입니다.

 

역시 코드를 보며 추가적으로 알아보겠습니다. 예시는 흔히 찾아볼 수 있는 직사각형, 정사각형 예시를 이용하겠습니다.

 

Code

직사각형 (Rectangle)

package lsp;

public class Rectangle {

    private int height;
    private int width;

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getArea() {
        return width * height;
    }
}

 

정사각형 (Square)

package lsp;

public class Square extends Rectangle{

    @Override
    public void setHeight(int height) {
        super.setHeight(height);
        super.setWidth(height);
    }

    @Override
    public void setWidth(int width) {
        super.setHeight(width);
        super.setWidth(width);
    }
}
  • 정사각형은 width, height가 같기 때문에 setHeight(), setWidth()를 오버 라이딩하였고, 너비를 구하는 getArea()는 동일하기 때문에 오버 라이딩하지 않았습니다.

실행 클래스

package lsp;

public class Main {
    public static void main(String[] args) {
        Rectangle rec = new Rectangle();
        rec.setHeight(4);
        rec.setWidth(5);

        int recArea = rec.getArea();
        System.out.println("recArea = " + recArea);

        
        Rectangle square = new Square();
        square.setHeight(4);
        square.setWidth(5);

        int squareArea = square.getArea();
        System.out.println("squareArea = " + squareArea);
    }
}
recArea = 20
squareArea = 25
  • 동일한 코드를 Rectangle의 하위 클래스인 Square로 바꿨더니 결과값이 다르게 나왔습니다.
  • 이는, 리스코프 원칙에 위배됩니다.

 

위배되는 이유

사실 정사각형은 수학적으로는 직사각형이라고 할 수 있지만, 이를 그대로 반영해 프로그래밍을 하게 되면 잘못된 프로그램이 될 수 있습니다.

 

위키피디아에서는 리스코프의 원칙을 보다 세분화하여 설명하고 있습니다. 그중 "하위형에서 선행조건은 강화될 수 없다."라는 내용이 있습니다. 즉, 자식 클래스에서 부모 클래스의 선행 조건을 강화시키면 안 된다는 이야기입니다. 

 

이 예시에 적용시켜 보자면, 자식 클래스인 Square에서는 "4 변의 길이가 모두 같아야 한다."라는 선행조건이 강화된 것입니다. 따라서 둘은 상속관계로 이어질 수 없는 클래스들이기 때문에 상속관계를 끊어서 프로그래밍을 해야 합니다.

만약 Rectangle클래스에서 if-else나 instanceof같이 객체의 타입을 비교해 서로 다른 행동을 하게 한다면, 이는 단일 책임원칙(OCP)에 어긋나게 됩니다.

 

 

'OOP' 카테고리의 다른 글

다형성이란?  (4) 2023.03.11
[OOP] SOLID - DIP(의존성 역전 원칙)  (2) 2022.12.23
[SOLID] ISP(인터페이스 분리 원칙)  (0) 2022.06.07
[OOP] SOLID - OCP(개방-폐쇄 원칙)  (0) 2022.05.25
[OOP] SOLID - SRP(단일책임원칙)  (0) 2022.05.23
Comments