public 상속은 "is-a(…는 ...의 일종이다.)" 를 의미한다.
이 말은 꼭 기억하도록 하자.
만약 Derived 클래스를 Base 클래스로 부터 public 상속을 통해 파생시켰다면, 이것은 컴파일러에게 다음과 같이 말한 것이다.
"Derived 타입으로 만들어진 모든 객체는 또한 Base 타입의 객체이지만, 그 반대는 되지 않는다"
즉 Base는 Derived 보다 더 일반적인 개념을 나타내며, Derived는 Base보다 더 특수한 개념을 나타낸다.
밴다이어그램으로 표현하면 다음과 같은 의미일 것이다.
C++는 public 상속을 이렇게 해석하도록 문법적으로 지원하고 있다.
위 예제는 public 상속에서만 통한다.
public 상속 = is-a 관계 <= 이 이야기는 꽤 직관적이고 간단하지만, 이런 직관성때문에 잘못 판단하는 경우가 있다. 예를 들어, 펭귄이 새의 일종이라는 사실은 누구나 알고, 새는 날 수 있다는 점도 사실이다. 이것을 C++로 표현하면 다음과 같은 코드가 나올 것인데
뭔가 이상함이 느껴진다. 위의 클래스 계통에 의하면 펭귄은 날 수 있다.
=> 자연어에 낚인 케이스이다. "새는 날 수 있다"라는 말이 모든 종류의 새에 대해 참인 명제가 아니기 때문이다. 따라서 조금 더 현실적으로 바꿔보자면
날 수 있는 새를 따로 분류하는 것이 조금 더 현실에 충실한 설계가 아닐까 싶다. 하지만 이는 현실에서의 이야기이고, 만약 어떤 소프트웨어를 설계하는데 비행관련 작업을 할 일이 없으면 이런 분류는 필요 없을 것이다. 즉 우리가 본뜨려고 하는 세계가 어떤 것이냐에 따라 고려해도 되고 안해도 그만인 것이다.
혹은 이런 방식으로 해결은 안될까?
펭귄이 상속받은 fly()를 재정의하여 에러가 나게 하는 것이다.
이 경우는 "펭귄이 날 수 없다" 가 아니라 "펭귄은 날 수 있다. 그러나 펭귄이 실제로 날려고 하면 에러가 난다" 이다.
실제로 날려고 하면 => 프로그램 실행때만 이 에러를 알 수 있다.
이 방법보단 그냥 fly()를 빼는 것이 더 좋다. 왜냐하면 펭귄이 fly()를 호출하면 컴파일 에러가 날 것이기 때문이다.
유효하지 않은 코드를 컴파일 단계에서 막아주는 인터페이스가 좋은 인터페이스이다.
예제를 하나 더보면, Square(정사각형) 클래스는 Rectangle(직사각형) 클래스로부터 상속받아야 한다고 생각할 수 있다. 수학적 정의로 보면 맞긴한데, 아래 코드를 보자.
example()의 두 단정문은 정사각형이면 실패해선 안된다. 당연히 정사각형의 가로 세로 길이는 같아야 하기 때문이다. 그런데 뭔가 이상함이 느껴진다.
- makeBigger() 호출 전, s의 가로 세로 길이는 같아야 한다.
- makeBigger() 호출 중, s의 가로 길이는 변하는데, 세로 길이는 변하면 안된다.
- makeBigger() 호출 후, s의 가로 세로 길이는 같아야 한다.
=> 말이 안된다. 왜 아런 문제가 발생했느냐? => 직사각형의 어떤 성질 중 정사각형에는 적용이 안되는 성질이 있는 것이다. 직사각형은 가로 세로 길이가 달라도 되지만, 정사각형은 같아야 한다!
public 상속은 기본 클래스 객체가 가진 모든 것들이 파생 클래스 객체에도 그대로 적용된다고 단정짓는 상속이다.
- public 상속의 의미는 "is-a(…는...의 일종)" 이다. 기본 클래스에 적용되는 모든 것들이 파생 클래스에 그대로 적용되어야 한다. 왜냐하면 모든 파생 클래스 객체는 기본 클래스 객체의 일종이기 때문이다.
'Effective C++ > 6. 상속, 그리고 객체 지향 설계' 카테고리의 다른 글
항목 37: 어떤 함수에 대해서도 상속받은 기본 매개변수 값은 절대로 재정의하지 말자 (0) | 2021.05.07 |
---|---|
항목 36: 상속받은 비가상 함수를 파생 클래스에 재정의하는 것은 절대 금물! (0) | 2021.05.04 |
항목 35: 가상 함수 대신 쓸 것들도 생각해 두는 자세를 시시때때로 길러 두자 (0) | 2021.05.03 |
항목 34: 인터페이스 상속과 구현 상속의 차이를 제대로 파악하고 구별하자 (0) | 2021.04.29 |
항목 33: 상속된 이름을 숨기는 일은 피하자 (0) | 2021.04.29 |