본문 바로가기

카테고리 없음

Class, Object, Instance 에 대한 글

가끔씩 OOP 관련된 강의나 동영상을 관심있게 보곤 한다.

이 사람은 어떤 관점으로 설명을 하고 있을까? 라는 관심이 이유다.

원론적인 설명을 하는 내용도 있지만, 대부분의 초보자를 위한 강의 영상에서는 이해를 돕기 위해 비유를 들어 설명하기도 한다. 그런데.. 그 내용이 썩 맘에 들지가 않는다.

최근에 자주 보이는 비유중 하나는 붕어빵(object)과 붕어빵틀(class) 라는 비유였는데 이건 class와 object의 관계를 오해하기 딱 좋은 비유라고 생각된다.

이 글은 그 이유에 대해 끄적여 볼 생각으로 쓰는 글이다.

 

붕어빵틀은 붕어빵이라는 object의 class가 맞는가?

class를 원론적으로 기술하자면, 세상 (그것이 현실이든 아니든)에 존재하는 '어떤 것(object)'을 코드로 옮기기 위해 추상화(abstraction)한 '정의(definition)'이다. 여기에서 '추상화' 라는 것은 object가 가진 특징들 중에 만들고자 하는 프로그램에서 필요로 하는 것들을 정의해서 '이러이러한 특징을 가진 것은 이 object이라 한다' 정도의 의미라고 보면 된다.

말이 좀 어려울텐데 예를 하나 들어보자..

마침 붕어빵을 이야기하고 있으니..

붕어빵이라는 object를 추상화 해본다면 여러 가지 특징들을 생각해 볼 수 있다.

붕어처럼 생긴 생김새라던지, 속을 채운 단팥 (요즘은 다른 것들로 채워지기도 하더라만..), 껍데기를 이루는 밀가루 반죽..

단순히 구성하는 내용을 필요로하는 프로그램이라면 이렇게 정의할 수 있을것이다.

그런데, 만들고자 하는 프로그램이 '붕어빵 타이쿤' 같은 게임이라면 여기에서 채울 특징들은 달라진다.

붕어빵 타이쿤에서는 붕어빵의 가격이 중요한 특징중 하나가 될 수 있다.

디아블로 같은 게임의 인벤토리에 들어갈 붕어빵이라면 몇 칸을 차지하는지도 중요한 특징이 될 수 있다.

 

이렇듯.. 추상화라는 것은 '세상'에 존재하는 '어떤 것'이 프로그램에서는 '어떤 특징'을 가지고 존재하는지를 정의하는 과정이라고 보면 된다. 그리고, 그 결과물이 class이다.

 

그렇다면 붕어빵과 붕어빵틀 이라는 비유로 object와 class를 설명하는 것이 올바른 비유인가?

붕어빵틀은 붕어빵을 만들어내기 위한 '도구'이고, 붕어빵의 외형을 결정한다. 그 틀에 밀가루 반죽과 팥을 얼마나 넣느냐에 따라 밀가루가 많이 들어간 붕어빵이 만들어지기도 하고, 팥이 많이 들어간 붕어빵이 만들어지기도 한다... 라는 것이 이를 설명하는 주된 내용들이다. 그럴싸해 보인다. 그런데, 이렇게 설명하면 붕어빵틀이 붕어빵을 찍어내는 틀이라는 관점에서 object를 만들어내는 틀이 class 라는 개념이 잡혀버리지 않을까? 그렇다면 추상화는? 붕어빵의 외형 외에 밀가루와 팥이 들어간다는 정의는 붕어빵 틀의 어느 부분에 들어있는걸까?

 

class에서 가장 중요한 것은 '추상화'의 과정

class와 object의 관계를 설명한다는 것은 결국 OOP라는 프로그래밍 기법에서 class와 object가 어떤 관계를 가지는가를 설명하는 것이 목적이다. 그 목적이 달성되려면 '추상화'가 빠질 수 없다. 현실세계에 존재하는 붕어빵이 가지고 있는 모든 특징들을 다 코드로 옮길 수는 없기 때문이다. 뭐.. 미친척하고 프로그래머가 생각할 수 있는 모든 특징을 코드로 만들 수도 있지 않냐.. 라고 할 수 있겠지만.. 프로그램에서 쓰이지 않을 특징들은 그냥 '코드 쓰레기'일 뿐이다. 그래서 추상화가 중요하다.

 

이해를 돕기위해 비유를 드는 것은 좋은 일이지만, 이 특징을 설명할 수 없는 비유를 해서는 안된다.

 

뜬금없는 소리지만, 우리는 Object-Oriented Programming을 이야기하고 있다. Class-Oriented Programming이 아니라..

즉, 출발점이 class가 아니라 object가 되어야 한다.

 

붕어빵이라는 object가 있다.

누군가가 당신에게 '붕어빵' 이라고 이야기하면 머리속에 떠오르는 붕어빵에 대해 떠오르는 것. 그게 바로 class다.

 

만약, 추운 겨울에 친구랑 길을 걷다가 '우리 뭐 먹을까?' 라는 대화 뒤에 나온 '붕어빵' 이라면 머리속에는 붕어 모양을 하고 속에 단팥이 들어있는 뜨거운 빵이 떠오를거다. (주머니 사정이 불편한 사람이라면 가격이 떠오를 수도 있겠다)

식중독이 걸려서 병원을 찾아간 환자에게 '어떤걸 먹었었나요?' 라는 질문에서 '붕어빵' 이라는 대답이 나왔다면 의사의 머리 속에는 만든지 얼마나 된 붕어빵인지, 곰팡이가 피어나있었거나 상한 속재료가 들어간 붕어빵인지의 여부가 더 중요한 붕어빵의 이미지일거다.

가계부를 쓰던 중이었다면 어제먹은 붕어빵의 가격이 더 중요할거다.

 

이렇듯, 어떤 object가 특정 상황에서 어떻게 추상화되어 정의되느냐는 것이 바로 class를 설명하는 주된 관점이어야 한다.

그리고, 이런 비유로 설명이 되어야 '어떤걸 먹었나'에서 출발하여 '음식'이라는 super class에서 붕어빵이라는 sub class를 설명할 수 있는 근거가 될 수 있으니.. 하나의 비유로 계속된 설명을 이어나갈 수 있다.

 

붕어빵틀과 붕어빵의 관계로 비유할 수 있는 것은 따로 있다

generic programming 이라는 프로그래밍 패러다임에 template라는 것이 있다. 이걸 설명할 때 주로 단어 의미 그대로 '거푸집'을 가지고 설명하는데.. 일반인들에겐 거푸집 보다는 붕어빵틀이 더 익숙할테니까 이녀석을 설명할 때 붕어빵과 붕어빵 틀의 비유를 드는 것은 적합한 경우라고 볼 수 있다.

똑같은 붕어빵 틀에 밀가루+팥을 넣으면 팥 붕어빵이 나오고, 밀가루+크림을 넣으면 크림붕어빵이 나오는 과정으로 설명할 수 있다. 이 과정에서 공통된 밀가루는 그대로 넣되, 속에 팥을 넣느냐 크림을 넣느냐에 따라 다른 붕어빵이 만들어지도록 '속'이 뭐로 만들어지냐만 정할 수 있도록 프로그램을 구성할 수 있다. template라는 것이 그런 프로그래밍 개념이다.

 

그렇다면 object와 instance의 차이점은?

딱히 이 글의 주제와는 연관이 없지만, 붕어빵틀이 등장하는 대부분의 강의영상에서 같이 다루는 것이니 이것도 살짝 짚고 넘어가자면..

instance라는 것은 그냥 object와 class의 관계를 의미하는 단어일 뿐이다. 구실좋게 '메모리에 존재하는 object'라는 설명들이 있던데.. 틀린 설명은 아니다만, 정확한 설명은 아니다.

instance의 원론적인 의미는 class와 그 class에 해당하는 object와의 관계를 의미하는데, class라는 '추상화'의 하나의 사례 (혹은 실체)인 object를 그 class의 instance라고 한다. instance라는 단어의 사전적 의미도 '사례'이다.

머리속에 떠오른 '붕어빵'이 class라면 손에 들고있는 '붕어빵'이라는 object는 내가 알고있는 '붕어빵'의 하나의 사례.. 즉 instance이다.

붕어빵과 계란빵을 같이 파는 가게에 가서 '붕어빵 먹자' 라고 한다면 붕어 모양의 따끈한 빵 이라는 class가 머리속에 떠오를테고, 붕어빵이라는 object와 계란빵이라는 object 중에 머리속 떠오른 생각(class)에 맞는 붕어모양으로 생긴 것을 집어서 먹게 될텐데, 붕어모양으로 생긴 것이 바로 머리속에 떠오른 '붕어빵'이라는 생각(class)에 딱 맞는 사례(instance)이기 때문이다.

 

맺는 글

비유라는 것은 이해를 돕는 좋은 수단이라고 생각한다. 하지만, 잘못된 비유 혹은 부적절한 비유는 그 순간에는 쉽게 이해할 수 있을지는 몰라도 깊이 파고들면 그 비유때문에 다음 단계로 넘어갈 때 중요한 점을 놓칠 수도 있고, 응용하는데 장벽이 되기도 한다. 누군가에게 지식을 공유하고 전달하는 것은 좋은 일이지만, 가능하면 보다 정확한 비유로 보다 더 도움되는 지식을 전달하는게 좋지 않을까?

 

- written by enigma