본문 바로가기

Java 기본 문법 - 참조 서적 [이것이 자바다 - 한빛미디어]/4. 객체지향 프로그래밍

9. Java 자바 - 패키지 (package)

패키지 (package)

 

많은 클래스들을 체계적으로 관리하기 위함이다.

폴더를 만들어서 파일을 저장하듯, 패키지를 만들어서 클래스를 저장 / 관리한다.

 

패키지의 물리적 형태는 파일 시스템의 폴더이다.

 

파일 시스템의 폴더 기능만이 아니라 클래스의 일부분이다.

 

- 패키지는 클래스를 유일하게 만들어주는 식별자 역할을 한다.

 

- 클래스의 전체 이름은 "패키지명 + 클래스명" 이다.

 

- 패키지가 상, 하위로 구분되어 있다면 도트 ( . ) 를 사용해서 표현한다.

 

상위패키지.하위패키지.클래스

 

ex) Car 클래스가 com.mycompany 패키지에 속해있다면,

 

- Car 클래스의 전체 이름 : "com.mycompany.Car"

 

- 실제 파일 시스템 : com\mycompany\Car.class

 

패키지가 중요한 이유!

클래스만 따로 복사해서 다른 곳으로 이동하면, 클래스는 사용할 수 없다!!

(이동 시 패키지 전체를 이동시켜야한다.)

 

ex) Car 클래스가 com.mycompany 패키지에 속할 경우, 파일 시스템 com\yourcompany 폴더에

강제로 이동하면 Car 클래스를 사용할 수 없다.

 

 

패키지 선언

 

패키지는 클래스를 컴파일 하는 과정에서 자동적으로 생성되는 폴더이다.

 

컴파일러는 클래스에 포함되어 있는 패키지 선언을 보고, 파일 시스템의 폴더로 자동 생성시킨다.

 

package 상위패키지.하위패키지;

public class ClassName { . . . }

 

패키지 이름은 개발자 임의로 지어도 되지만, 지켜야 할 규칙이 있다.

 

    - 숫자로 시작해서는 안되고, _ , $ 를 제외한 특수 문자를 사용해서는 안 된다.

 

    - java로 시작하는 패키지는 자바 표준 API에서만 사용하므로 사용해서는 안 된다.

 

    - 모두 소문자로 작성하는 것이 관례

 

여러 개발 회사가 함께 참여하는 대규모 프로젝트나 다른 회사의 패키지를 이용해서 개발할 경우,

패키지 이름이 중복될 가능성이 있다.

패키지가 서로 중복되지 않도록 회사의 도메인 이름으로 패키지를 만든다.

도메인 이름으로 패키지 이름을 만들 경우, 도메인 이름 역순으로 패키지 이름을 지어준다.

(포괄적인 이름이 상위 패키지가 되도록 하기 위함)

마지막에는 프로젝트 이름을 붙여주는 것이 관례이다.

 

com.samsung.projectname
com.hyndai.projectname
com.lg.projectname
ort.apache.projectname

 


 

패키지 선언이 포함된 클래스 컴파일

 

패키지 선언이 포함된 클래스를 명령 프롬프트에서 컴파일할 경우

단순히 javac ClassName.java 로 컴파일해서 패키지 폴더가 생성되지 않는다.

 

패키지 폴더가 자동으로 생성되려면 javac 명령어 + -d 옵션을 추가하고

패키지가 생성될 경로를 다음과 같이 지정해야 한다.

 

javac -d . ClassName.java            // 현재 폴더 내에 생성
javac -d ..\bin ClassName.java       // 현재 폴더와 같은 위치에 bin 폴더에 생성
javac -d C:\Temp\bin ClassName.java  // 지정된 폴더에 생성

 

ex) Application.java 가 C:\Temp 폴더에 작성되었을 때

Application.java

package sec12.exam01_package_compile;

public class Application {
    public static void main(String[] args) {
        System.out.println("어플을 실행합니다.");
    }
}

 

명령 프롬프트에서 C:\Temp 로 이동 후 아래와 같이 컴파일 한다.

 

C:\Temp>javac -d . Application.java

 

컴파일이 성공되면 패키지 폴더 내부에 Application.class 가 생성된다.

 

Application.class는 main( ) 메소드가 선언되어 실행 가능하다.

 

패키지에 소속된 클래스를 명령프롬프트에서 실행하려면 바이트 코드 파일(.class) 이 있는 폴더에서

java 명령어를 사용해서는 안된다.

 

패키지는 클래스의 일부분이므로, 패키지가 시작하는 폴더에서 java 명령어를 사용해야 한다.

 

즉, C:\Temp 폴더에서 java 명령어를 실행해야 한다.

 


 

이클립스에서 패키지 생성과 클래스 생성

 

패키지만 따로 생성할 수 있고, 클래스 생성 시 동시에 생성할 수 있다.

보통 패키지를 먼저 생성하고 해당 패키지에서 클래스를 생성하는 방법을 주로 사용한다.

 

프로젝트의 src 폴더에서 [File - New - Package], 오른쪽 마우스[New - Package] 에서 패키지를 생성한다.

 

이클립스 패키지 생성

 

상위패키지 sec12 와 하위패키지 exam01_package_create 는 ( . ) 도트로 구분해서 입력한다.

 

프로젝트의 src 폴더에서 [File - New - class], 오른쪽 마우스[New - class] 에서 클래스를 생성한다.

 

이클립스 클래스 생성

 

이클립스에서는 src 의 모든 내용을 컴파일해서 bin 폴더에 생성시킨다.

 

package Explorer 뷰에는 bin 폴더가 보이지 않기 때문에, Navigator 뷰에서 확인할 수 있다.

(Navigator 뷰는 [Window - Show View - Navigator]를 선택하면 볼 수 있다.)

 

bin 폴더에는 컴파일 된 바이트 코드 파일(.class)을 볼 수 있다.

 

이클립스에서 패키지 선언이 없는 클래스는 default 패키지에 포함시킨다.

(default 패키지는 사실상 패키지가 없다는 의미이다. 패키지를 만들어서 클래스를 관리하는 것이 좋다.)

 


 

import 문

 

같은 패키지에 속하는 클래스들은 아무런 조건 없이 다른 클래스를 사용할 수 있지만,

 

다른 패키지에 속하는 클래스를 사용하려면 2 가지 방법 중 하나를 선택해야 한다.

 

1. 패키지와 클래스를 모두 기술하는 방법

 

ex) com.hankook 패키지에 소속된 Tire 클래스를 이용해서 필드 선언 후 객체 생성

package com.mycompany;

public class Car {
    com.hankook.Tire tire = new com.hankook.Tire();   // 객체 생성
}

 

com.hankook.Tire : 타입

tire : 필드명

new com.hankook.Tire( );  : 객체 생성

 

패키지 이름이 짧을 경우 불편함이 없지만,

길거나, 이렇게 사용해야 할 클래스가 많다면 패키지 이름을 붙이는 것은 전체 코드를 난잡하게 보일 수 있다.

 

2. import 문 사용 (주로 사용)

 

사용하고자 하는 패키지를 import 문으로 선언하고, 클래스를 사용할 때는 패키지를 생략한다.

 

package com.mycompany;

import com.hankook.Tire;
[또는 import com.hankook.*; ]

public class Car {
    Tire tire = new Tire();
}

 

- import 문 작성 위치 : 패키지 선언과 클래스 선언 사이에 선언된다.

 

- 패키지에 포함된 다수 클래스를 사용해야 한다면, 모든 클래스를 의미하는 * 기호를 사용한다.

 

- import 문의 개수 제한은 없다.

 

 

import 문 사용 시 주의할 점

 

import 문으로 지정된 패키지의 하위 패키지는 import 대상이 아니다!!

만약 하위 패키지의 클래스를 이용하고 싶다면 import 문을 하나 더 작성해야 한다.

 

ex) com.mycompany 패키지의 클래스 + com.mycompany.project 패키지의 클래스를 둘 다 사용하려면

아래와 같이 두 개의 import 문을 사용해야 한다.

 

import com.mycompany.*;
import com.mycompany.project.*;

 

 

패키지 이름 전체 기술하는 1 번 방법이 꼭 필요한 경우

 

서로 다른 패키지에 동일한 클래스 이름이 존재하고, 두 패키지가 모두 import 되어 있는 경우이다.

자바 컴파일러는 어떤 패키지에서 클래스를 로딩할 지 결정할 수 없어서 컴파일 에러가 발생한다.

 

이 경우에는 정확한 패키지 이름 전체를 기술해야 한다.

 

ex) 서로 다른 패키지에 소속된 Tire 클래스

 

서로 다른 패키지 속의 같은 이름의 Tire 클래스 존재

 

3 개의 패키지를 모두 사용하는 Car.java

package sec12.exam03_import.mycompany;

import sec12.exam03_import.hankook.*;
import sec12.exam03_import.hyndai.Engine;
import sec12.exam03_import.kumho.*;

public class Car {
    //필드
    Engine engine = new Engine();
    
    SnowTire tire1 = new SnowTire();
    BigWidthTire tire2 = new BigWidthTire();
    
    sec12.exam03_import.hankook.Tire tire3 = new sec12.exam03_import.hankook.Tire();
    sec12.exam03_import.kumho.Tire tire4 = new sec12.exam03_import.kumho.Tire();
}

 

Tire 클래스는 import 된 두 패키지에 모두 있기 때문에 패키지 이름과 함께 전체 이름이 기술 되어야 한다.

 

Engine 클래스는 hyndai 패키지에만 존재하기 때문에 문제 없다. (다른 클래스도 마찬가지)

 

 


 

* 이클립스에서 import 문 자동적으로 추가하기

 

현재 작성 중인 클래스의 메뉴에서 아래와 같이 선택한다.

 

Source → Organize imports ( 단축키 : Ctrl + Shift + O )

 

 

* 이클립스에서 자동으로 "import 패키지.*;" 로 추가하는 방법

 

1. Window → Preference → Java → Code Style → Organize imports 선택

 

2. Number of imports needed for.* 의 99를 1로 변경하고 [OK] 누른다.

 

3. 다시 [ Ctrl + Shift + O ] 를 누른다