한 줄 요약하면, 코드에서 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를 변경해서는 안된다.