" A Type hierarchy is composed of subtypes and supertypes. The intuitive idea of a subtype is one whose objects provide all the behavior of another type(the supertype) plus something extra. What is wanted here is something like the following substitution property: if for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2, then s is a subtype of T." -> 1987년 MIT 컴퓨터 공학과 리스코프 교수 - LSP의 일반화 관계를 설명한 원문 中
ex) 원숭이는 포유류이다.
public class Bag {
private int price;
public void setPrice(int price){
this.price = price;
}
public int getPrice() {
return price;
}
}
// 모든 Bag 객체 b와 모든 정수 값 p에 대해
[be.setPrice(p)].getPrice() == p;
public class DiscountedBag extends Bag{
private double discountedRage = 0;
public void setDiscounted(double discountedRate) {
this.discountedRage = discountedRate;
}
public void applyDiscount(int price) {
super.setPrice(price - (int)(discountedRage * price));
}
}
Bag | DiscountedBag |
---|---|
Bag b1 = new Bag(); | DiscountedBag b3 = new DiscountedBag(); |
Bag b2 = new Bag(); | DiscountedBag b4 = new DiscountedBag(); |
b1.setPrice(50000); | b3.setPrice(50000); |
System.out.println(b1.getPrice()); | System.out.println(b3.getPrice()); |
b2.setPrice(b1.getPrice()); | b4.setPrice(b1.getPrice()); |
System.out.println(b2.getPrice()); | System.out.println(b4.getPrice()); |
public class DiscountedBag extends Bag{
private double discountedRage;
public void setDiscounted(double discountedRate){
this.discountedRage = discountedRage;
}
public void setPrice(int price){
super.setPrice(price - (int)(discountedRate * price));
}
}
A. 그렇지 않다.
p - (int)(discountedRate * price) != p;
피터 코드의 상속 규칙 중에 "서브 클래스가 슈퍼 클래스의 책임을 무시하거나 재정의하지 않고 확장만 수행한다"라는 규칙과 슈퍼 클래스의 메서드를 오버라이드 하지 않는 것과 같은 의미로 해석할 수 있으며, 피터 코드의 상속 규칙을 지키는 것은 곧 LSP를 만족시키는 하나의 방법에 해당한다.
Reference