
한 줄 요약하면, 코드에서 super class의 object가 있을 자리에 derived class의 object를 가져다 놓아도 문제가 없어야 한다.이다.
상술한 문장 그 자체로 이해가 쉽지만, 다른 원칙들에 비해 비교적 formal하게 rule이 정의가 되어있으므로 지난하더라도 하나하나 살펴보도록 하자.
참고로, 후술에서 표현의 간결함을 위해 아래와 같이 용어를 사용하도록 하겠다.
feed(Cat c)과 같이 정의되어 있고, 코드의 어느 곳엔가 super_obj.feed(cat)과 같은 코드가 존재한다고 해보자.super_obj.feed(cat)을 derived_obj.feed(cat)와 같이 치환했을 때, 문제 없이 동작하도록 만들라는 것이다.derived_obj.feed method의 parameter type은 똑같이 Cat을 인자로 받거나(i.e. feed(Cat c)) 더 추상화된 object를 인자로 받아야 한다(i.e. feed(Animal a)).Cat GetOldest()과 같이 정의되어 있고, 코드의 어느 곳엔가 Cat oldest_cat = super_obj.GetOldest()와 같은 코드가 존재한다고 해보자.super_obj를 derived_obj로 치환해도 문제가 없으려면 derived method는 정확히 일치하는 return type을 갖거나(i.e. Cat GetOldest()) 보다 덜 추상화가 된 return type을 가져야 한다(i.e. BengalCat GetOldest()).super_obj를 derived_obj로 치환했을 때의 문제점을 떠올려보면 이해가 편하다.DoSomething(int x)와 같은 양수/음수를 모두 받을 수 있는 method를 derived method에서 음수를 받으면 exception을 throw하는 식으로 상속하지 말라는 이야기이다.Rule 5) derived method는 super method의 post-condition을 약화하면 안된다.
super_obj.DoSomething()을 호출한 후의 상황과 derived_obj.DoSomething()을 호출한 후의 상황을 동일하게 만들어주어야 한다는 이야기이다.super_obj.DoSomething()가 모든 TCP/IP connection을 disconnect하는 일을 수행한다고 해보자.derived_obj.DoSomething() 역시 모든 TCP/IP connection을 끊어야지, 뭔가를 남겨두면 안된다.Rule 6) derived method는 super method의 invariant를 보존해야 한다.
super_obj.DoSomething()을 호출한 후에 바뀌지 않는 것이 보장되었던 것들을 derived_obj.DoSomething()을 호출 후에도 보장해주어야 한다는 이야기이다.Rule 7) derived method는 super method의 private field를 변경해서는 안된다.