이제 슬슬 OOP를 배워보도록 하겠습니다. ArrayList는 동적 배열입니다. 이 클래스 내부에 있는 변수들을 봅시다.

 

 

 elementData와 size입니다. elementData는 ArrayList의 실제 데이터들을 저장해 놓은 배열입니다. 그리고, size는 배열 리스트의 크기를 의미합니다. 이 둘을 가지고 어떠한 연산을 할 수 있을까요?

 

 

 기능 중 하나인 add입니다. 이 함수 내에서, size와 elementData를 쓰고 있다는 것을 알 수 있어요. 그러면, 필드인 size와 실제 데이터를 담아두는 배열인 elementData. 이것과 기능인 add를 묶었나요? 즉, 메소드와 필드들을 하나로 묶었다고 할 수 있어요.

 

 

 그러면 이들이, arrayList라는 클래스 안에 wrapping 되어 있다고도 말할 수 있을 거에요. 이렇게 메서드와 필드들을 잘 묶는 것을 캡슐화라고 이야기 합니다.

 

 


 여기서 문제. size와 element_data라는 변수를 모르는데 add라는 것을 쓸 수 있을까요?

 

 

 쓸 수 있습니다. 분명한 것은 안에 있는 elementData라는 배열의 grow rate가 1.5라는 것을 모르고도 쓸 수 있어요. 공간이 모자랄 때 어떻게 확장을 해야 하는지 모르고도 쓸 수 있어요. add 안에 ensurexxxx 라는 함수가 들어 있어요. ensurexxxx 안에 또 ensure~가 있고, 그 안에 grow가 있는데요. 이 셋을 모두 알아야 add 메서드를 쓸 수 있는 것이 아닙니다. 그것을 모르고도 우리는 add를 쓸 수 있어요.

 

 그런데, 우리는 elementData라던지, grow라던지, ensurexxxx 같은 것들을 바깥에서 호출할 수 없다는 것을 알 수 있습니다.

 

 

 심지어, elementData도 Main class에서 바로 부를 수 없다는 것을 알 수 있습니다.

 

 

 이것은 왜 그럴까요? 생각해 보면 간단합니다. grow는 실제 데이터의 capacity를 늘리는 일을 합니다. 그런데, 우리가 생각없이 grow를 60번 호출했다고 해 봅시다. grow rate는 1.5입니다. 1.5^40은 60억 xxxx 입니다.

 

 

 숨겨야 하는 기능임은 부정할 수 없어요. 따라서, grow 함수 앞에는 private가 붙어 있습니다.

 

 

 element_data는 어떨까요? 바깥에서도 부를 수 있다면, arr.element_data[0] = 10; 이런 식으로 arrayList에 있는 값을 어딘가에서 함부로 바꿀 수 있을 거에요. 그러니까 쉽게 이야기 하면, 집에 들어오는데 열쇠를 가지고 들어와야 하는데, 옥상으로 올라가서 줄을 타고 내려온 다음에 창문에 접근한 꼴이 되어버립니다.

 

 arrayList에서 element_data의 값을 바꾸기 위해서, set이라는 메서드를 제공합니다.

 

 

 단순히 arr.elementxxx[0] = 0; 이렇게 접근하지는 못합니다. elementxxx 배열은 Main 클래스에서 접근할 수 없게 가려졌기 때문입니다. 다만, arr.set(0,0)을 통해서 elementxxx[0]의 값을 바꿀 수는 있습니다.

 

 

 캡슐화된 멤버를 접근 제어자를 써서 보호한 것입니다. 그렇게 함으로써, set을 통해서만 element_data[0]에 접근해서 값을 변경할 수 있습니다. 이를 데이터 은닉화라고 이야기 합니다.