오늘은 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를 붙이면 내부에서만 보이게끔 합니다. 이 정도면 짚고 넘어가셔도 크게 문제는 없으리라 생각이 듭니다.
'코딩 > Java' 카테고리의 다른 글
메모리릭 : gc가 쓰레기는 잘 수거하는데 무슨 문제라도 있나요? (4) | 2020.03.17 |
---|---|
java : 도달 가능한 객체가 무엇일까요? (0) | 2020.03.08 |
java final 필드 : 초기화 후에 값을 변경하지 못하게 한다. (6) | 2020.01.16 |
java 생성자 : 객체가 생성되고 나서 호출이 된다. (8) | 2019.12.14 |
java this : 현재 객체를 참조한다. (0) | 2019.12.08 |
최근댓글