effective-java 를 읽다 `리스코프 치환 원칙`에 대한 내용이 나왔는데 내용이 잘 생각나지 않아 정리하려 한다.
리스코프 치환 원칙이란?
컴퓨터 프로그램에서 자료형 S
가 자료형 T
의 하위형이라면 필요한 프로그램의 속성(정확성, 수행하는 업무 등)의 변경 없이 자료형 T
의 객체를 자료형 S
의 객체로 교체(치환)할 수 있어야 한다는 원칙이다. 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.
상위 타입을 전달받는 메서드 구현
public class BirdUtil {
private BirdUtil() {
}
public static void fly(Bird bird) {
bird.fly();
}
}
상속 관계의 클래스(Bird <-- Sparrow)
public class Bird {
public void fly() {
System.out.println("난다.");
}
}
public class Sparrow extends Bird {
@Override
public void fly() {
System.out.println("참새가 난다");
}
}
상위 타입을 전달받는 메서드에서 하위 타입을 전달받더라도 정상적으로 동작해야 한다.
public void fly() {
BirdUtil.fly(new Bird());
BirdUtil.fly(new Sparrow());
}
잘못된 상속 관계는 리스코프 치환 원칙에 위배된다.
public class Chicken extends Bird {
@Override
public void fly() {
throw new IllegalStateException(); //닭은 날 수 없음
}
}
리스코프 치환 원칙을 지키지 않았을 때 발생하는 문제점 예시
public class Rectangle {
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
private int width;
private int height;
public void setWidth(int width) {
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
public int area() {
return width * height;
}
}
public class Square extends Rectangle {
public Square(int width, int height) {
super(width, height);
}
@Override
public void setWidth(int width) {
super.setWidth(width);
super.setHeight(width);
}
@Override
public void setHeight(int height) {
super.setHeight(height);
super.setWidth(height);
}
}
정사각형은 너비가 늘어났을 때, 높이도 늘어나게 된다.즉, 상위 타입의 정확성을 깨뜨리게 된다.
@Test
@DisplayName("리스코프 치환 법칙을 위배하는 예시")
public void squareAndRectangle() {
// given
final Rectangle rectangle = new Rectangle(5, 5);
final Square square = new Square(5, 5);
// then
assertThat(rectangle.area()).isEqualTo(square.area());
// when
rectangle.setWidth(10);
square.setWidth(10);
// then
assertThat(rectangle.area()).isNotEqualTo(square.area());
}
'객체지향설계 5원칙(S.O.L.I.D)' 카테고리의 다른 글
I. 인터페이스 분리 원칙(Interface Segregation Principle) (0) | 2022.01.21 |
---|---|
O. 개방-폐쇄 원칙(Open-Closed Principle) (0) | 2022.01.10 |
S. 단일 책임 원칙(Single Responsibility Principle) (0) | 2022.01.10 |