본문으로 이동
메뉴 여닫기
환경 설정 메뉴 여닫기
개인 메뉴 여닫기
로그인하지 않음
지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.

리스코프 치환 원칙(Liskov Substitution Principle, LSP)은 상위 타입의 객체를 쓰는 자리에 그 하위 타입의 객체를 넣어도 프로그램이 기대한 대로 동작해야 한다는 객체지향 설계 원칙으로, SOLID의 L 에 해당한다.

이 원칙은 바버라 리스코프(Barbara Liskov)가 1987년 기조연설에서 제시하고, 1994년 지넷 윙(Jeannette Wing)과 함께 쓴 논문 「A Behavioral Notion of Subtyping」에서 정식화했다. 논문은 하위 타입 관계를 메서드 이름과 시그니처가 아니라 행위(behavior) 로 정의한다. 상위 타입 객체에 대해 증명할 수 있는 성질은 하위 타입 객체에 대해서도 성립해야 하며, 이를 위해 하위 타입의 메서드는 상위 타입 메서드의 사전조건을 강화하지 않고 사후조건을 약화하지 않아야 하고, 상위 타입의 불변식과 이력 제약도 지켜야 한다.[1]

로버트 C. 마틴(Robert C. Martin)은 1996년 칼럼에서 이 원칙을 "기반 클래스의 포인터나 참조를 쓰는 함수는 파생 클래스의 객체를 그것인 줄 모르고도 쓸 수 있어야 한다"로 풀어 쓰고, 정사각형-직사각형 예로 설명했다. 뒤에 이 원칙은 객체지향 설계 원칙 다섯 가지(SOLID)에 들어갔다.[2]

무엇을 점검하는가

편집 원본 편집

LSP 는 상속(일반화)이 올바르게 쓰였는지 판단하는 기준이다. 상속 구문이 문법적으로 맞더라도 하위 클래스가 상위 클래스의 약속을 깨면 상속을 잘못 쓴 것이다.

  • 하위 클래스의 메서드가 상위 클래스보다 까다로운 입력 조건을 요구한다(사전조건 강화)
  • 하위 클래스의 메서드가 상위 클래스가 보장하던 결과를 보장하지 않는다(사후조건 약화)
  • 하위 클래스가 상위 클래스의 메서드를 빈 몸체로 두거나 "지원하지 않음" 예외를 던진다
  • 호출하는 쪽이 instanceof 로 실제 타입을 확인해 분기해야만 올바르게 동작한다

정사각형-직사각형 예

편집 원본 편집

정사각형은 수학적으로 직사각형의 일종이라 Square extends Rectangle 로 두기 쉽다. 그런데 직사각형은 "너비만 바꾸면 높이는 그대로"라는 약속을 갖는다. 정사각형은 너비를 바꾸면 높이도 같이 바뀌어야 하므로 이 약속을 지킬 수 없다. 직사각형을 받아 너비를 5, 높이를 4 로 설정한 뒤 넓이가 20 이라고 확인하는 코드에 정사각형을 넘기면 넓이가 16 이나 25 가 되어 실패한다. 컴파일은 아무 문제 없이 된다.

컴파일러가 잡아 주지 않는다

편집 원본 편집

자바·C++·C# 의 컴파일러가 상속 관계에서 검사하는 것은 시그니처(메서드 이름, 매개변수 타입, 반환 타입, 접근 제한자, 던지는 검사 예외)뿐이다. LSP 가 요구하는 사전조건·사후조건·불변식은 코드의 의미이므로 타입 검사기가 알 수 없다. 그래서 LSP 를 어겨도 컴파일 오류가 나지 않는다. 위반은 실행 중의 잘못된 결과나 예외로 드러나며, 단위 테스트(상위 타입용 테스트를 하위 타입마다 돌리는 방식), 계약에 의한 설계(Design by Contract) 도구, 코드 리뷰로 찾아야 한다.[1]

다른 SOLID 원칙과 구별하기

편집 원본 편집
원칙 핵심 문장 무엇을 보는가
SRP(단일 책임) 클래스는 변경 이유가 하나뿐이어야 한다 클래스의 책임 범위
OCP(개방-폐쇄) 확장에는 열리고 수정에는 닫혀야 한다 기존 코드를 고치지 않고 기능을 더할 수 있는가
LSP(리스코프 치환) 하위 타입은 상위 타입을 대체할 수 있어야 한다 상속(일반화)이 행위까지 맞게 쓰였는가
ISP(인터페이스 분리) 쓰지 않는 메서드에 의존하지 않아야 한다 인터페이스의 크기
DIP(의존관계 역전) 구체가 아니라 추상에 의존해야 한다 변하기 쉬운 것 대신 잘 변하지 않는 추상에 의존하는가

LSP 를 지키면 OCP 도 지키기 쉬워진다. 하위 클래스를 새로 더해도 상위 타입을 쓰는 코드를 고칠 필요가 없기 때문이다.[2]

  1. ↑ 1.0 1.1 Barbara H. Liskov·Jeannette M. Wing, 「A Behavioral Notion of Subtyping」, ACM Transactions on Programming Languages and Systems 16(6), 1994, https://www.cs.cmu.edu/~wing/publications/LiskovWing94.pdf, 확인일: 2026-11-04.
  2. ↑ 2.0 2.1 Robert C. Martin, 「The Liskov Substitution Principle」, The C++ Report, 1996, https://www.cs.utexas.edu/~downing/papers/LSP-1996.pdf, 확인일: 2026-11-04.