오늘은 Java의 객체, 클래스에 대해서 알아보도록 하겠습니다. 돌아 돌아 여기까지 오기는 했는데. OOP의 컨셉을 5 ~ 7편에 걸쳐서 잡도록 하겠습니다. 클래스는 설계도, 객체는 설계도 대로 만들어진 실체로 생각하시면 편한데요. 예제 프로그램을 보면서 이해해 보도록 하겠습니다.

 

 조금 쉬운 예제가 뭐가 있을까요?

 

 


 자판기를 예로 들어 봅시다. 실제로 자판기는, 물건이 여러 개가 있고, 물건이 없는 경우도 처리를 해야 합니다만. 여기에서는 간단하게, 물건은 셀 수 없을 정도로 너무 많이 있고, 1가지 물건만 판다고 해 봅시다. 그러면 우리는 자판기가 해야 할 일을 2가지로 요약할 수 있을 겁니다.

 

 

 get_item과 put_money 이렇게 2개로요. 그러면 자판기의 상태는 어떻게 표현하면 좋을까요? 일단, 어떠한 사람이 물건을 사기 위해서 얼마나 넣어는지, 그리고 item의 가격을 표현하면 될 겁니다.

 

 

 그러면, 이들을 토대로 구현해 봅시다.

 

 

 먼저, 상태를 표현해 봅시다. cost[]는 물건들 (예를 들어 콜라와 같은)의 가격을 의미합니다. 가격이 100원인데, 30원만 넣었습니다. 아이템이 나오면 안 되겠죠. put_cost는 투입된 액수입니다. 예를 들어, 1000원짜리 지폐를 넣고, 500원짜리 동전을 넣었다면 이 값은 1500이 될 겁니다.

 

 만약에, 물건을 선택해서, 자판기에서 아이템이 나왔다면, 거스름돈을 돌려주고, 아이템이 나왔다고 할 겁니다. 만약에, 그렇지 않은데, get_item을 하려고 한다면, 돈을 더 넣으라고 하면 될 겁니다.

 

 

 이를 토대로 기능들을 구현해 보면 위와 같아요. put_money는 x를 인자로 하나 받아요. 30원을 넣었다. 등등. 만약에 돈을 넣으면 put_cost의 값을 증가시키면 됩니다. 그리고, get_item은 아이템을 꺼내는 함수입니다. 만약에, 돈을 충분히 넣어서 item을 살 정도가 된다면 거스름돈과, 물건을 줘야 할 겁니다. 그렇지 않으면 더 넣어야 할 거고요. 그 처리는 18번째 줄에서 하고 있습니다. 이렇게, 속성과 기능을 정의한 것을 class라고 합니다. user defined type이라고도 이야기 합니다.

 

 


 설계도대로 구현이 된 실체를 우리는 Object라고 합니다.

 

 

 보통, 우리는 new 연산자로 객체를 생성합니다. 예를 들어 34번째 줄은 자판기 객체를 생성한 것입니다. 이 상황을 그림으로 그려 봅시다. 먼저, new vending_machine()에서, 5번째 줄의 생성자가 호출이 됩니다.

 

 

  그러면 인스턴스 필드, private int로 선언된 put_cost와 cost 배열이 heap 영역에 생성이 될 겁니다.

 

 

 7 ~ 8번째 줄에서 배열 객체가 생성이 되고, 생성자 함수가 끝나면, 아래와 같이 그려질 겁니다. 그러면 우리는 vm.put_money(3); 과 같이 . 연산자를 통해서, 접근할 수 있어요.

 

 

객체.(객체변수|메소드)

 

 

 그러면, 아래 프로그램은 어떻게 동작할까요?

 

 

 만약에, put_money라는 것을 vm과 vm2가 공유한다면, need, get, need, get 순서대로 출력이 되어야 할 겁니다. 출력 결과는 어떻게 나올까요?

 

 

 need, get, need, need 가 나와버립니다. 이는 vm과 vm2의 put_money가 별개의 공간에 할당이 되어 있기 때문입니다.

 

 

 그런가요? static 변수는 그렇지 않습니다.

 

 

[관련글]

[코딩/Java] - java 클래스 변수 : 어떻게 메모리에 올라갈까?

 

 

각 클래스별로 공통된 특성을 가질 수 있는 것은 static으로 선언을 한다고 했어요. 예를 들자면, 트럼프 카드에서, 카드들의 너비와 폭은 모두 같습니다. 그런데, 자판기의 특성인 put_money는 각 자판기마다 공통적으로 가져야 할 특성이 결코 아닙니다. 예를 들어서, 100만개의 자판기가 있었다고 합시다. 제가 남한산성입구역의 승강장 안에 있는 기계에 1000원을 넣었다고 해 봅시다. 그러면 모든 기계에 1000원이 들어간 상태가 되어야 하나요? 아니겠죠.

 

 즉, put_money는, 각 기계마다 독립된 값을 가져야 합니다. 따라서, 인스턴스 멤버로 선언을 해야 합니다.

 

 

 그렇다면, vm.put_cost와 vm2.put_cost는 별개의 메모리 공간에 할당되기 때문에, 39번째 줄이 끝난 후, vm2.put_cost는 35가 됩니다. 100보다 작기 때문에, need 65가 출력됩니다.