독서노트Effective_C++_조항32: 당신의public상속상속소형출is-a관계 확정

6146 단어 effective
이 조항은 공유 상속의 논리를 말하는데 상속을 사용하고 상속이 공유 상속이라면 반드시 자류가 부류(is-a관계)임을 확보해야 한다.이런 논리는 생활 속의 상리와 일치하지 않을 수 있다. 예를 들어 펭귄은 알을 낳고 모든 펭귄은 조류의 일종이다. 직관적으로 보면 우리는 공유 계승으로 묘사할 수 있다.
 1 class Bird
 2 {
 3 public:
 4     virtual void fly(){cout << "it can fly." << endl;}
 5 };
 6 
 7 class Penguin: public Bird
 8 {
 9     // fly()      ,         fly()  ,         
10 };
11 
12 int main()
13 {
14     Penguin p;
15     p.fly(); //
16 }

그런데 문제는 펭귄이 새지만 새가 날 수 있는 기술이 펭귄에게 적용되지 않는다는 점이다. 이 문제를 어떻게 해결해야 할까?방법1, Penguin의fly() 방법에서 이상을 던지고 p.fly()를 호출하면 실행할 때 이 이상을 포착합니다.이 방법은 그다지 좋지 않다. 왜냐하면 그것은 운행할 때 비로소 문제를 발견하기 때문이다.
방법 2, 버드의 플라이(fly) 방법을 제거하고 중간에 플라잉버드류(fly) 방법이 있음)와 NotFlyingBird류(fly() 방법이 없음)를 덧붙인 다음 펭귄에게 NotFlyingBird류와 계승하도록 한다.이 방법도 좋지 않다. 주의력을 분산시키고 계승의 차원이 깊어지면 코드를 이해하기 어렵고 유지하기 어렵다.
방법 셋째, 모든 버드가 반드시 가지고 있는 공통성(예를 들어 알을 낳고 부화)을 보존하고, 버드의 fly() 방법을 제거하고 다른 날 수 있는 새의 자류에만 이 방법을 단독으로 쓴다.fly () 방법을 정의하지 않았기 때문에 Penguin 대상이 fly () 를 호출하면 컴파일링 기간에 오류가 발생합니다.
어려운 방법 셋을 선택한 후에 우리는 고개를 돌려 생각했다. 바로 모든public 계승의 배후에서 부류의 모든 특성을 만족시킬 수 있도록 해야 한다(부류는 날 수 있고 자류는 반드시 날 수 있다). 추상적으로 말하면 부류를 사용할 수 있는 곳에서 반드시 자류를 사용하여 교체할 수 있다.
 
이것이 바로 Liskov 대체 원칙이 우리에게 알려준 것이다. 어떤 부류가 나타날 수 있는 곳이든 부류는 반드시 이 부류를 대체할 수 있다. 소프트웨어 기능이 영향을 받지 않을 때만 부류가 진정으로 복용될 수 있다.통속적으로 말하면'자류는 부류의 기능을 확장할 수 있지만 부류의 원래 기능을 바꿀 수 없다'는 것이다.
 
다음은 수학의 예를 하나 더 살펴보자. 기초 기하학에서의 장방형과 정방형에 대해 선생님은'정방형은 특수한 장방형'이라고 말씀하실 것이다.'특수'는 길이와 넓이가 서로 같다. 글씨체로 보면 우리는 is-a 관계로 표현할 수 있다.
 1 class Rectangle
 2 {
 3 protected:
 4     int length;
 5     int width;
 6 public:
 7     void virtual IncreaseLength(int DeltaLength)
 8     {
 9         length += DeltaLength;
10     }
11 };
12 
13 class Square: public Rectangle
14 {
15 public:
16     void virtual IncreaseLength(int DeltaLength)
17     {
18         length += DeltaLength;
19         width += DeltaLength;
20     }
21 };

정사각형의 길이와 폭을 유지하는 등 값의 특성을 유지하기 위해 인크리에이션 Length에서도 width를 조작해야 했다. 이 단계에 이르러 구성원 함수명인 인크리에이션 Length가 맛이 변한 것 같다. 분명히 길이를 늘렸지만'몰래'도 폭을 바꿨다.이것은'자류는 부류의 기능을 확장할 수 있지만 부류의 원래 기능을 바꿀 수 없다'는 것과 배치된다. 그래서 이 is-a 관계는 수학 세계에서도 이렇게 말할 수 있지만 프로그램의 세계에서는 성립되지 않는다!
 
상기 두 가지 예를 들면public상속이 말처럼 쉽지 않다는 것을 알 수 있다. 두 종류가 진정으로 is-a관계가 될 수 있는지 이해하려면 잘 고려해야 한다.마지막으로 요약:
'public 계승'은 is-a를 의미한다.베이스 클래스에 적용되는 모든 일은derived 클래스에도 적용됩니다. 모든derived 클래스 대상도 베이스 클래스 대상이기 때문입니다.

좋은 웹페이지 즐겨찾기