본문 바로가기

Homo Faber/Concepts

자바에서 상속

Q : 자바 관련 서적들이 상속에 대해 은근히 편이적인 비유나 표현으로 대강 넘어 가는 것 같아 상속 개념에 대해 상당히 혼란스럽습니다. 부모클래스가 자식클래스에게 상속을 할때, 자신의 맴버를 완전히 물려주는 것인지(참조나 이동) 아니면 그 복사본을 물려주는 것인지가 궁금합니다.
이것이 명백해져야 super나 this을 이해할 때 좀더 정확할 것 같습니다.
이것이 분명치 않아 어떤 책들은 super나 this가 무슨 맴버를 참조할때는 예외라는 등 이상한 소리를 하면서, 이해가 아닌 '외우기'로 몰아가고 있습니다.
고수님들의 속시원한 답변 부탁드리겠습니다.

A : 클래스라는 단어부터 정의를 해야될 듯 싶은데요, 왜냐하면 작성하신 분께서 질문하신 부모클래스가 자식클래스에게 자신의 멤버를 복사본을 물려주는 지에 대한 것부터 해결하려고 합니다.

우선 클래스는 가장 흔히 이야기하듯이 붕어빵을 만드는 틀이라고 할 수 있겠네요.
물론, 이 문장에 대해서 여러가지의 해석이 가능하겠지만, 이걸 명제로 시작하겠습니다.

자바에서의 클래스와 객체라는 개념은 설계나 분석, 구현시에 반드시 따지고 넘어가야 할 것들입니다. 쇼핑몰의 예를 들면, '어떠한 고객이 주문을 한다' 라는 현상을 가지고, 클래스, 객체를 뽑아보겠습니다. 여기서의 객체는 클래스의 인스턴스, 즉 위의 명제로 말하자면, 붕어빵이라고 말할 수 있겠습니다.
우선 클래스를 뽑아내면, 크게 '고객' 과 '주문' 이라는 클래스를 뽑아낼 수 있을겁니다. 그렇다면, 이에 상응하는 객체는 위의 문장에서 뽑아낸다면 어떻게 되겠습니까?
결론적으로 말해서, 위의 현상을 나타내는 문장은 일반적인 현실 세계를 묘사한 문장이 아니라, 가장 일반화시킨 문장이라고 볼 수 있습니다. 이는 UML 에서 말하는 유스케이스와 유스케이스 시나리오와의 관계와도 같습니다. 위의 상황은 '홍길동이라는 고객이 삼성컴퓨터를 산다.' 라고 말해야지 현실세계에서 일어나는 상황을 그대로 묘사했다고 말할 수 있을겁니다. 즉, 객체는 일반화된 문장에서는 뽑아낼 수는 없고, 해당 상황을 그대로 묘사한 문장에서만 가능하다고 볼 수 있을 겁니다.
수정된 상황에서, 객체는 '홍길동' 이라는 '고객 클래스' 와, '삼성 컴퓨터' 라는 '제품 클래스' 로 뽑아낼 수 있습니다. 여기서 일반화시킨 문장에서 뽑아낸 클래스와 상황을 그대로 묘사한 문장에서 뽑아낸 클래스가 다르게 되었습니다.
만일, 설계자가 경험이 많다면, 아니, 조금만 생각을 해보면, '산다' 라는 문장을 '주문한다' 라는 의미로 해석될 수 있음을 알 수 있을 겁니다. 다시, 이 문장을 더 세분화하여 묘사한다면, '홍길동은 2003년 12월 24일 쇼핑몰에서 삼성에서 제조한 모델 OO 컴퓨터를 홍길순에게 선물하기 위해서 주문했다.' 라는 문장으로 바꿀 수 있을 겁니다. 이제 명확하게 객체와 클래스가 뽑아져 나올겁니다. 상황에 대한 묘사는 5W1H를 기준으로 상세하게 묘사되어야 올바른 객체와 클래스가 뽑아져 나올 수 있습니다. 실제로 일반화시킨 문장에서는 뽑아져 나오지 않은 클래스인, '제품', '주문일', '쇼핑몰', '공급업체', '모델명', '배송받는 사람', '구매 목적' 등이 더 나올 수 있습니다.

이처럼, 클래스를 기준으로 객체가 나오는 것이 아니라, 어떤 특수한 상황을 토대로 일반화시킨 것, 즉, 객체를 기준으로 일반화시킨 클래스를 도출하는게 일반적으로 사람이 생각할 수 있는 범주일 것입니다. 클래스와 객체라는 개념도 여러가지 인스턴스에 대한 개념을 객체라 하고, 이러한 인스턴스를 추상화시킨 개념을 클래스라고 하자 라고 정의를 내렸을 것입니다. 객체지향 개념을 접근하실 때에 개념위주로 생각하시다 보면 세부적인 상황에 대해서 무시할 수도 있습니다. 이 점을 유의하시고 접근을 하셔야 합니다.

다시 처음에 질문하신 문장으로 되돌아간다면, 부모클래스와 자식클래스는 모두 '클래스' 입니다. 처음 명제에서 클래스는 '붕어빵을 만드는 틀'이라고 말씀을 드렸는데요, 부모 클래스든, 자식 클래스든 모두 하나의 틀이기 때문에 그 자신이 모든 멤버를 가지고 있다고 볼 수 있습니다. 즉, 부모에게도 a 라는 멤버가 있다면, 자식에게도 a 라는 멤버를 그대로 가지고 있게됩니다. 이는, 부모의 멤버를 복사한 것도, 참조한 것도 아닌 고유의 멤버라는 점입니다. 그렇다면, 이는 과연 어떠한 원리로 선언도 되지 않은 멤버를 자식이 가지게 되는지 의문이 생깁니다. 이에 대한 해답은 '메타클래스' 라고 하는 클래스의 클래스에서 찾을 수 있습니다. '메타클래스'는 클래스를 생성시키는 역할을 합니다. 즉, 클래스를 생성시키면 객체가 되듯이 메타클래스를 생성시키면 클래스가 됩니다. 자식클래스는 이 메타클래스에서 생성이 될때에 부모의 모든 멤버를 포함해서 생성을 시킵니다. 이것은 참조나 복사하고는 또 다른 의미입니다. 자바에서는 이러한 메타클래스의 개념을 API에 포함시켰는데요, java.lang.Class 라는게 바로 그겁니다.

아무튼, 상속의 개념은 클래스의 또 다른 확장으로 생각하시면 됩니다. 일반적으로 객체지향 언어를 사용하시는 분들이 헷갈리는 점이, 상속과 연관(association, composition 이라고도 함)인데요, 연관은 일반적으로 말하는 참조하고 비슷한 개념이고, 상속은 위에서 말씀드린 대로 부모의 모든 속성을 하위가 그대로 가지게 되는 확장입니다.
그리고, 예외라는 것은 이러한 개념을 토대로 제약이나 특수사항을 둔 것이라 보시면 될 것 같습니다.

반응형