클래스나 메서드를 공부하면서 가장 헷갈리고 있는 (ing) 지점이 처음 배우는 한정자의 개념이다.
물론 JS를 공부하며 찍먹한 적은 있으나 실제로 활용한 적은 없어서 배우는 내내 마주하는 public static void main (String[] args)
의 각각의 요소를 이해하고 작성하는데도 얼마간의 시간이 필요했다.
물론 지금이야 psvm
이라는 Intelli J의 단축어도 알아내어 요긴하게 쓰고 있기는 하지만 말이다.
나에게 자바는 매우 흥미로운 언어다.
JS나 C++을 공부하면서는 순서대로 코드를 쳤다면, 자바에서는 이러한 요소들을 한 파일의 면에 나열하는 것이 아니라 메서드로, 필드로 표현하며 여러 개의 클래스가 상호작용하는 모양새를 가지고 있기 때문이다. (물론 JS나 C++도 여러가지 요소가 상호작용하기는 하지만,,)
무엇인가 인간 세상과 닮은 꼴이랄까, 그런 생각이 들었다.
각설하고, 이제 헷갈리는 메서드의 구성 하나하나에 대한 정리를 시작해보겠다.
각각의 요소가 해당 필드/메서드를 정의할 때 어떤 의미를 주는가에 대해서는 의미를 찾았으나, 명확한 깨달음을 얻기 위해서는 자료를 좀 더 찾아봐야 할 필요가 있다.
한정자는 클래스, 인터페이스, 그리고 그 내부의 구성요소들의 성격을 결정하는 키워드로 메서드를 선언할 때 메서드명 앞쪽에 위치한다.
한정자는 접근제한자, abstract, final, static 등(몇몇 개 더 있다)이 있는데, 이를 함께 명시하여 해당 요소의 특성을 쉽게 확인할 수 있다.
예시는 메서드를 들고 있으나, 접근제한자, abstract, final, static 등의 한정자는 제각기 사용될 수 있는 요소들이 다르며 다음의 각 파트에서 이를 확인할 수 있다.
클래스나 메서드 등의 선언 시 접근 제한자는 접근 한정자라고도 하며, 메서드나 필드로 접근할 수 있는 권한의 범위를 지정해주는 역할을 한다.
접근 제한자는 총 4가지로 [public
/ protected
/ default
/ private
]이 있다.
이 4가지의 접근 제한자는 앞서 말했듯 접근할 수 있는 권한의 범위를 기준으로 나누어져 있으며, 그 권한을 갖는 주체는 (메서드가 선언되어 있는)해당 클래스
/ 해당 클래스가 속해있는 패키지
/ 하위 클래스
/ 그 외
로 4개의 주체가 있다.
위 나열한 순서대로 [public
/ protected
/ default
/ private
] 접근 가능한 범위를 알아보자.
접근제한자가 public인 메서드는 공공의
라는 그 의미 그대로 클래스 외부, 패키지 외부에서도 접근이 가능하다.
해당 클래스
/ 해당 클래스가 속해있는 패키지
/ 하위 클래스
/ 그 외
접근제한자가 protected인 메서드는 어디서나 접근이 가능한 것은 아니고, 해당 클래스가 속해있는 패키지 내부나 이를 상위 클래스로 하고 있는 클래스까지 접근이 가능하다.
해당 클래스
/ 해당 클래스가 속해있는 패키지
/ 하위 클래스
접근제한자가 default인 메서드는 우리가 접근제한자를 명시하지 않았을 경우 적용되는 기본 접근제한자이다.
이 경우, 해당 클래스와 해당 패키지 내 클래스들에서 접근할 수 있고, 후손 클래스라도 다른 패키지에 속해있는 경우에는 접근이 불가능하다.
해당 클래스
/ 해당 클래스가 속해있는 패키지
접근제한자가 private인 메서드는 의미 그대로 해당 클래스 내부에서만 접근할 수 있는 권한을 갖는다.
해당 클래스 내부가 아닌 다른 어떤 위치에서도 접근할 수 없다.
값을 갖고 있는 필드의 경우 private을 많이 사용하며, 외부 클래스에서 직접 이용할 수 없으므로 Getter와 Setter 등의 메서드를 이용하여 이 값을 조회하거나 저장한다.
해당 클래스
/ 해당 클래스가 속해있는 패키지
이 두 표현은 동일한 위치에 오는 한정자들이 아니다. 하지만 나는 위 두 개념을 혼동했기 때문에, 이 두 한정자를 함께 정리하기로 했다.
추상 클래스를 공부한 현재는 abstract까지 첨가되어 함께 올 수 있는 표현인지, 만약 함께 올 수 있다면 어떻게 쓰여야 하는지 등의 추가적인 의문들이 포함되었다... 하지만 어제 공부했으므로 추상 클래스 편을 올릴 때 정리하도록 하자.
static 수식자는 클래스 구성요소에 부여할 수 있는 수식자로 메서드, 필드의 성격까지 나타낸다. 위에 명기한 대로 인터페이스 또한 구성요소에 static 한정자를 사용할 수 있다.
final 한정사는 상수로 지정해주는 메서드이다. 인터페이스의 메서드를 지정하는 데에는 사용할 수 없고, 이외 클래스를 선언할 때 선두, 인터페이스나 클래스의 필드, 그리고 클래스의 메서드를 지정하는 데에는 사용이 가능하다.
실제로 Intelli J에서 실험해본 결과, final 수식자의 경우, interface의 필드에서는 적용가능하지만, 메서드에서는 사용할 수 없다는 에러 메세지를 받을 수 있었다.
위 한정사에 관한 여러가지 궁금증들을 실행해보고 몇 가지 사실을 얻을 수 있었다.
(원인 파악해보기)
static final
의 순서로 사용된다.this.
는 인스턴스 개체를 지칭하고 있기 때문에 클래스 메서드인 static 메서드에서는 사용이 불가하다.반환타입은 만약 당신이 Java의 데이터 타입을 알고 있다면 어려울 것이 없다.
해당 메서드가 반환하는 값이 어떤 타입인지 명시해주는 부분이다.
String, int, double... 등등 다양한 데이터 타입이 있으나 이 반환 타입에는 데이터 타입에는 존재하지 않는 void
라는 메서드만의 개별적인 타입이 하나 있다.
void는 실행은 하되 값을 리턴하지 않는 형태의 메서드를 의미한다.
메인 함수를 선언할 때, JAVA에서는 다음과 같이 작성한다.
public static void main (String[] args) {실행 코드}
그리고 c++에서 우리가
int main() {
... ...
return 0;
}
와 같이 main 함수에서 항상 0을 반환해야하는 것과 달리, 어떤 값을 반환하지 않아도 된다.
하지만 JVM은 반환값이 없는 그 함수를 실행시키고, 종결시킨다.
바로 그 반환하지 않는 메서드를 void
라는 한정사로 붙여 표현하는 것이다.
JAVA는 모를 때 보면 코드를 이해하기 쉽지 않은 언어지만, 공부를 하다보니 유용한 점이 아주 많은 언어인 것 같다.
JS를 공부할 때, 객체나 클래스 같은 자료구조들을 공유하여 사용하기 때문에 JAVA가 단순히 JS와 비슷한 언어이지만 데이터 타입을 명시해주는 언어라고 느꼈다..
하지만 실제 코드를 쳐보면서 C++이나 JS와는 다른 구조적 형태
를 갖는 것이 매우 흥미롭고, 이후 서버를 구축하면서도 JAVA의 구조적 특징
을 활용하면 여러 클래스들을 유기적으로 연결하여 더욱 쉽게 읽히고, 분류된 프로그래밍을 할 수 있을 것이다.
접근 제한자 또한 흥미로운 부분 중에 하나이다. 앞서 말한 것처럼 JS에서도 static이나 public 같은 접근 제한자들을 공부한 적이 있으나 실제로 프로젝트에서 활용한 경험은 없다.
접근 권한을 부여하는 이 행위들을 통해 정보 은닉의 필요성을 스스로 결정할 수 있는 계기가 되지 않을까 싶다.
우선 확인한 내용들을 정리해보았으나 JAVA에는 더 많은 내용들이 있겠지.
이를 활용하기 위해서는 내가 위 한정사들을 공부하며 이해한 내용들을 실제 프로그래밍 내에서 다양하게 사용하는 내용들이 필요하다.
더욱 다양한 JAVA의 라이브러리들 또한 프로그래밍을 하는 또 다른 재미요소가 되지 않을까하는 기대를 하며 오늘의 글을 마친다.