코딩로그
[SOLID] LSP_리스코프 치환 원칙 본문
[LSP]
- 리스코프 치환 원칙
- Liskov Substitution Principle
- OCP를 가능하게 해주는 원칙
- 부모 객체와 이를 상속한 자식 객체가 있을 때 부모 객체를 호출하는 동작에서 자식 객체가 부모 객체를 완전히 대체할 수 있어야 함
- 자식 클래스는 부모 클래스처럼 똑같은 요청에 대해 똑같은 응답을 할 수 있어야 하고, 이때 응답의 타입 또한 같아야 함
- 자식 클래스에서 overriding 해 부모 클래스에서 구현된 method를 재정의하는 행위 == 부모 클래스의 책임 무시
- 일관성 위반
- 자식 클래스는 부모 클래스가 따르던 계약 사항을 따라야 함
- 선행 조건 == 모듈을 호출하기 위해 참이어야 하는 조건
- 후행 조건 == 모듈이 동작한 뒤 참이어야 하는 조건
- 자식 클래스에서 선행 조건은 강화될 수 없다
- 자식 클래스에서 후행 조건은 약화될 수 없다
- 자식 클래스에서 부모 클래스의 불변 조건은 반드시 유지되어야 한다
- 자식 클래스를 구현하는 개발자가 기존 프로그램이 문제없이 안정적으로 작동할 수 있도록 가이드라인을 알려주는 원칙
- ex) 문서 작성 프로그램 → 구버전에서 작업한 내용, 신버전에서 계속 사용할 수 있어야 함
- 해결 방법
- 상속 관계 제거
- @Override 재정의 X → 많은 고려 필요
[Example]
- Bad Example
- Square class가 Rectangle class 대체 불가능
- 같은 명령에 대해 다른 결과 출력
// LSP Bad Example
// Square class가 Rectangle class 대체 불가능
class Rectangle {
int width;
int height;
public void setHeight(int height) {
this.height = height;
}
public int getHeight() {
return this.height;
}
public void setWidth(int width) {
this.width = width;
}
public int getWidth() {
return this.width;
}
public int area() {
return this.width * this.height;
}
}
class Square extends Rectangle {
@Override
public void setWidth(int length){
this.width = length;
this.height = length;
}
@Override
public void setHeight(int length){
this.width = length;
this.height = length;
}
}
public class MyClass {
public static void main(String args[]) {
Rectangle rectangle = new Rectangle();
Square square = new Square();
rectangle.setHeight(3);
rectangle.setWidth(2);
square.setHeight(3);
square.setWidth(2);
System.out.println("rectangle area : " + rectangle.area()); // 6
System.out.println("square area : " + square.area()); // 4
}
}
- Good Example
- Rectangle과 Square class 사이의 상속 관계 해제 방식 사용
// LSP Good Example
// Rectangle과 Square class 사이의 상속 관계 해제
abstract class Shape{
abstract int area();
}
class Rectangle extends Shape{
int width;
int height;
public void setHeight(int height) {
this.height = height;
}
public int getHeight() {
return this.height;
}
public void setWidth(int width) {
this.width = width;
}
public int getWidth() {
return this.width;
}
public int area() {
return this.width * this.height;
}
}
class Square extends Shape {
int length;
public void setLength(int length) {
this.length = length;
}
public int getLength() {
return this.length;
}
public int area() {
return this.length * this.length;
}
}
public class MyClass {
public static void main(String args[]) {
Rectangle rectangle = new Rectangle();
Square square = new Square();
rectangle.setHeight(3);
rectangle.setWidth(2);
square.setLength(3);
System.out.println("rectangle area : " + rectangle.area()); // 6
System.out.println("square area : " + square.area()); // 9
}
}
'YJ > 관련 이론' 카테고리의 다른 글
[SOLID] DIP_의존 역전 원칙 (0) | 2022.09.25 |
---|---|
[SOLID] ISP_인터페이스 분리 원칙 (0) | 2022.09.25 |
[SOLID] OCP_개방 폐쇄 원칙 (0) | 2022.09.24 |
[SOLID] SRP_단일 책임 원칙 (0) | 2022.09.24 |