오늘은 Java의 접근 제어자 중에서, private와 public에 대해서만 알아보도록 하겠습니다. 나머지 2개는 상속이랑, 패키지에 대해서 배우고 언급하도록 하겠습니다. 사실 저 혼자서 개발할 때에는 그냥 Class를 구조체 쓰듯이 다 public으로 선언해 버리고, 다른 클래스에서 접근 가능하게 할 수 있습니다. 그냥 내 마음대로 짜면 되니까요. 그랬으면 좋겠어요.


  A 클래스는 위와 같습니다. packA에 선언이 되어 있습니다. public으로 선언된 a가 있고, private로 선언된 b가 있습니다.

 

 

 프로젝트의 구조는 다음과 같습니다. packA에 있는 A 클래스가 있고요. main 함수는, Main 패키지의 Main 클래스 안에 있습니다. 메인 함수에서 A 객체를 하나 생성하였습니다.

 

 A의 필드 a에는 접근이 가능합니다. 이 상황을 그림으로 그려 봅시다.

 

 심지어 Main은 A와는 아무런 관계도 없는 class 입니다. 그러면, public으로 선언된 필드는, 어떠한 클래스에서도 접근 가능하다고 생각해도 될까요? 그렇게 생각해도 큰 문제는 없어 보입니다. 그런데 Main 클래스와 A 클래스는 다른 패키지에 있습니다. 그렇기 때문에, Main에서, packA.A를 import 해야 합니다. 조금 더 나아가서 생각해 봅시다. Java가 제공하는 (java.util에 있는) 자료구조들 중에서 ArrayList는 생각보다 많이 썼을 겁니다. 이것도 패키지 어딘가에 있을 겁니다.

 

그런데, add에 접근할 수 있습니다. ArrayList와 아무런 관련이 없는 Main 클래스에서도요.

 

 

 이는, add 메서드가 public으로 선언이 되었기 때문입니다. 그런데, java.util.ArrayList를 import 하지 않으면 접근할 수 없어요. Main과 ArrayList의 add는 다른 패키지에 있기 때문입니다.

 


 그런데, 기능이나, 필드를 선언된 클래스 클래스 내에서만 보이게 가려야 할 때가 있습니다. 이 때, 붙일 수 있는 키워드는 private입니다. 영어 단어로 비밀이란 뜻이니 비밀스럽게 뭔가 가려놓기는 했을 겁니다. A 클래스를 다시 한 번 봅시다.

 

 

 Main에서 A 인스턴스를 생성했을 때, A.a 이렇게는 접근이 가능했습니다. 하지만, b는 안 보였는데요. 이는 b가 가려졌기 때문입니다.Main 클래스는 A 입장에서 보았을 때에는 바깥에 있기 때문입니다.

 

 

 그러면, 같은 패키지 안에 C라는 클래스를 선언했습니다. 그리고 C의 어떤 메서드 안에, A 인스턴스를 새로 생성한 다음에, 접근을 합니다. 이 때에는 어떻게 될까요? 똑같습니다. 같은 패키지에 있다고 하더라도, C는 A의 외부에 있는 것이라는 것은 변하지 않습니다.

 

 

 그렇기 때문에, 이 경우에도, A의 a는 보이지만 b는 안 보입니다. C는 A 입장에서 보았을 때에는 외부에 있기 때문입니다.

 

 

 그런데, A 내부에서 my_A 메서드 안에서는 b 필드에 접근이 가능했습니다.

 

 

 이는, A 내부에 my_A라는 함수가 있기 때문입니다. 그러니, my_A에서 필드 b에 접근하는 것 또한 가능합니다.

 

 


 그러면, 이것도 같이 생각해 봅시다. 필드는 private로, 메서드는 public으로 선언하는 것이 국룰이라는데.. 그런데, 무조건 메서드는 public으로 선언하라고 하는 법은 없습니다. 상황에 따라서는 private로 선언해야 할 경우도 있는데요. ArrayList를 우리가 쓸 때, grow와 같은 메서드는 부를 수 없습니다.

 

 

 왜 그럴까요? grow 함수는, array의 공간을 1.5배로 확장시켜주는 역할을 합니다. 우리가 다른 클래스에서 이 함수를 부주의하게 다루어서, ArrayList 객체에서, grow 기능을 50번 수행하게 한다면 어떻게 될까요? 1.5의 50승은 6.37억입니다. 부주의하게 50번을 호출한 것 치고 댓가가 상당히 클 수 있습니다.

 

 즉, grow는 외부에 보여져셔는 안 되는 기능 중 하나입니다. 그러면, 이 기능은 어디에서 호출이 될 법한 것인가요?

 

 

 추가될 수 있는지를 검사할 때, 호출이 될 법 합니다. 그런데, 이 두 함수 또한 private로 선언이 되어 있습니다. 이들은 언제 호출이 될까요? add를 보겠습니다.

 

 

 add에서, ensureCapacity 메서드를 호출합니다. ensurexxx 계열은 둘째 치고 grow는 외부에 노출되어서는 안 되는 것이죠. 그렇기에, ArrayList 클래스의 add 안에서 안전하게 처리할 수 있도록 해 줍니다.

 

 

즉, 외부에 보여도 되는 기능, 속성과, 내부에만 보여야 되는 기능과 속성을 분리해야 하는데요. private를 붙이면 내부에서만 보이게끔 합니다. 이 정도면 짚고 넘어가셔도 크게 문제는 없으리라 생각이 듭니다.