본문 바로가기
Java/Java Basic

[Java Basic] 18. 패키지와 Import

by Rosmary 2022. 7. 16.
728x90
반응형

 

 

 

 

1. Java의 Package는 무엇인가?

 

 

지금까지 필자가 작성한 Java 포스팅에서, 필자는 이제 프로그래밍을 시작하는 독자분들을 위해 하나의 .java 파일에 하나 이상의 클래스를 통째로 작성하여 예시를 들어왔었다. 하지만 Java에서 .java 파일이 컴파일되어 하나의 class 파일을 생성한다는 것을 상기해보면, 하나의 .java 파일에는 하나의 객체에 대한 내용만 클래스로 작성하는 것이 올바른 방법이다.

 

 

 

 

 

위의 코드는 필자가 클래스 상속과 관련된 내용에 대해 설명하면서 사용한 코드다. ClassEx.java 파일에 무려 3개의 클래스 코드가 작성이 되어 있는데, 클래스 Cessna150과 FA18EF는 각각 Cessna150.java, FA18EF.java 파일에 별도로 작성을 하는 것이 좋다는 의미다.

 

 

 

그리고 클래스 종류가 하나 둘 증가하다보면, 이 .java파일들도 관리를 위해 "폴더"를 나누어 저장해야 할 필요가 있다. 

Java에서 파일 구분을 위한 폴더를 "패키지(Package)"라고 한다.

 

필자는 이제 새 프로젝트로 코드를 작성할 것인데, 공군과 해군으로 패키지를 만든 뒤, 각 패키지에 해/공군의 비행기 기종에 대해 정의된 클래스 파일을 만들려고 한다.

 

패키지를 만드는 것은 크게 어렵지 않다. Eclipse와 같은 IDE 프로그램을 사용하지 않는 분들이라면, 프로젝트를 진행하는 폴더에서 클래스를 구분하여 저장할 폴더를 단순히 생성하기만 하면 된다.

 

 

 

Eclipse를 사용한다면 좌측 탐색기 창에서 프로젝트 -> Src 폴더 아이콘을 우클릭 하고, New -> Package를 선택한뒤 Package 이름을 지정/생성해주면 된다.

 

 

 

만들어진 패키지의 아이콘은 흰 바탕에 격자무늬를 가진 박스 4개가 포개진 모양이다. 이제 필자는 Airforce 폴더에 AirforceF16과 AirforceF18을, Navy 폴더에는 NavyF14과 NavyF18 클래스를 만들어보려 한다. 각 .java 파일이 패키지 내에 저장되면, 흰색 배경이 주황색 배경으로 변경될 것이다.

 

좌: 미 공군 F16, 우: 캐나다 공군 F18
좌: 미 해군 F14, 우: 미 해군 F/A-18E/F

 

그리고 이 클래스들을 호출할 Main 함수가 포함된 Class는 어떠한 패키지에도 속하지 않도록 src에서 새 파일을 만들어 작성했다.

 

 

 

 

아직까진 별다른 내용을 채우지 않고 클래스 뼈대만 만들어 각각의 패키지에 저장한 상태다. 하지만, 이 상태에서 Eclipse를 보면, 패키지 내에 저장된 .java 파일은 전부 에러가 발생하는 것을 확인할 수 있다. 

 

 

 

2. package 예약어

 

이유는 매우 단순한데, Java에서 패키지 내에 속하는 클래스 파일의 경우, 반드시 해당 .java 파일이 속한 패키지를 코드로 명시해주어야 하기 때문이다. 특정 패키지에 소속되어 있음을 나타내는 Java 예약어는 package다. 사용법은 아래와 같다.

 

package 클래스파일이_속한_패키지명;

 

이 package 예약어는 반드시 .java 파일의 가장 윗 부분에 명시되어야 한다. 수동으로 .java 파일에 작성할 수도 있으나, Eclipse로 코드를 작성하는 분들이라면, 모든 .java 코드를 기본 패키지인 default package로 이동한 뒤, 다시 각 패키지에 재배치해보자. 처음 작성한 코드에 추가로 package 코드가 생성된 것을 확인할 수 있다.

 

 

 

그리고 이 package 코드가 생성됨과 동시에, 각 패키지 내 .java 파일의 에러가 모두 사라진 것을 확인할 수 있다.

 

보통 Java에서 제공하는 클래스 파일의 경우, 종류가 매우 많기 때문에 마치 트리구조의 패키지 형태를 이루고 있다. Java Documentation을 보면 패키지 이름이 온점(.)으로 구분된 형태가 매우 많은데, 이는 패키지의 하위 구조를 의미하는 것이다. 즉, 기본 패키지인 java.lang의 경우, java 패키지 아래에 존재하는 lang 패키지라는 뜻이다.

 

 

특정 클래스가 패키지 내의 다른 패키지에 존재하는 경우, 아래와 같이 온점으로 패키지명을 구분하면 된다.

 

 

 

 

3. import 예약어

 

이제 Main.java 파일에서 패키지에 저장한 각 클래스 파일을 호출하여 인스턴스를 생성해보자. 지금까지 하나의 .java 파일에서 여러 클래스를 생성했던 때와 달리, 인스턴스 생성 과정에서 에러가 발생함을 알 수 있다.

 

 

패키지 안에 존재하던 모든 .java 파일을 다시 default package로 옮겨보자. 다시 에러가 사라지는 것을 확인할 수 있다.

 

 

 

그럼, 패키지에 포함된 .java 파일은 어떻게 호출해야 할까?

 

패키지에 포함된 .java 파일을 부르기 위해서는 패키지와 .java 파일명을 사용한다고 선언해주어야 한다. 이 때 사용하는 예약어는 import다. import의 사용 방법은 아래와 같다.

 

import 패키지명.클래스명;

 

Main 함수에서 import 문을 사용하여 패키지 내에 위치한 .java 파일로부터 인스턴스를 생성하는 방법은 아래와 같다.

 

 

 

import 문을 작성했음에도 불구하고 에러가 발생하는 이유는 패키지 내에 존재하는 클래스가 외부에서 호출이 호출이 불가하도록 설정되어 있기 때문이다. 이러한 권한을 설정하는 것을 제어자라고 하는데, 이는 바로 다음 포스팅에서 다루어 볼 예정이다. 패키지 내의 각 클래스 코드의 시작부분에 public을 넣어주면 모든 에러는 사라진다.

 

 

 

위의 내용을 토대로, 글자를 입력받을 때 사용하는 Scanner 클래스와 System.in 코드를 다시 살펴보자. Scanner 클래스를 사용하려면 .java 파일의 상단에 import java.util.Scanner를 입력한다. 그러나 System 클래스 사용을 위해 별도의 import 문을 작성하지 않는다. 이는 System 클래스가 java.lang 패키지에 존재하는 클래스이기 때문인데, Java는 모든 .java 파일의 상단에 자동으로 import java.lang.*; 코드를 삽입하기 떄문이다.

 

 

import 문 사용 시, 패키지 뒤에 클래스 명 대신 별표(*)를 입력하면, 해당 패키지 내의 모든 클래스를 사용할 수 있도록 만든다는 것이다. java.lang.*의 경우 System, Math 등 프로그래밍에 필요한 기본 패키지가 포함되어 있는데, 이들 패키지 import 선언 없이 바로 사용이 가능한 이유가 이 때문이다.

 

 

 

참고로 동일한 패키지에 위치한 .java 파일을 참조/호출해야하는 경우 별도로 import 문을 사용할 필요가 없다. 서로 같은 경로(위치)에 파일이 존재하기 때문이다.

 


 

 

다음 포스팅에서는 클래스의 제어자에 대해 알아보려한다.

 

 

 

Fin.

 

반응형

댓글