프로그램이 작고 단순해서 클래스가 몇 개 없다면 괜찮겠지만, 기능이 점점 추가되어서 프로그램이 아주 커지게 되면 매우 많은 클래스가 등장하면서 관련 있는 기능들을 분류해서 관리하고 싶을 것이다.
User
UserManager
UserHistory
Product
ProductCatalog
ProductImage
Order
OrderService
OrderHistory
ShoppingCart
CartItem
Payment
PaymentHistory
Shipment
ShipmentTracker
컴퓨터는 보통 파일을 분류하기 위해 폴더, 디렉토리라는 개념을 제공한다. 자바도 이런 개념을 제공하는데 이것이 바로 패키지다.
* user
* User
* UserManager
* UserHistory
* product
* Product
* ProductCatalog
* ProductImage
* order
* Order
* OrderService
* OrderHistory
* cart
* ShoppingCart
* CartItem
* payment
* Payment
* PaymentHistory
* shipping
* Shipment
* ShipmentTracker
여기서 `user`, `product`등이 바로 패키지이다. 그리고 해당 패키지 안에 관련된 자바 클래스들을 넣으면 된다.
패키지 사용
패키지를 먼저 만들고 그 다음에 클래스를 만들어야 한다. 또한 패키지 위치에 주의해야 한다.
pack.Data
package pack;
public class Data {
public Data() {
System.out.println("패키지 pack Data 생성");
}
}
- 패키지를 사용하는 경우 항상 코드 첫 줄에 `package pack`과 같이 패키지 이름을 적어주어야 ㅎ나다.
- 여기서는 `pack` 패키지에 `Data` 클래스를 만들었다.
pack.a.User
package pack.a;
public class User {
public User() {
System.out.println("패키지 pack.a 회원 생성");
}
}
- `pack` 하위에 `a`라는 패키지를 먼저 만들고 `pack.a` 패키지에 `User` 클래스를 만든다.
생성자에 `public`을 사용했는데 다른 패키지에서 이 클래스의 생성자를 호출하려면 `public`을 사용해야 한다.
pack.PackageMain1
package pack;
public class PackageMain1 {
public static void main(String[] args) {
Data data = new Data();
pack.a.User user = new pack.a.User();
}
}
- 사용자와 같은 위치: `packageMain1`과 `Data`는 같은 `pack`이라는 패키지에 소속되어 있다. 이렇게 같은 패키지에 있는 경우에는 패키지 경로를 생략해도 된다.
- 사용자와 다른 위치: `packageMain1`과 `User`는 서로 다른 패키지이다. 이렇게 패키지가 다르면 `pack.a.User`와 같이 패키지 전체 경로를 포함해서 클래스를 적어주어야 한다.
패키지 - import
이전에 본 코드와 같이 패키지가 다르다고 `pack.a.User`와 같이 항상 전체 경로를 적어주는 것은 불편하다. 이때는 `import`를 사용하면 된다.
package pack;
import pack.a.User;
// import pack.a.*;
public class PackageMain2 {
public static void main(String[] args) {
Data data = new Data();
User user = new User(); //import 사용으로 패키지 명 생략 가능
}
}
- 코드 첫 줄에는 `package`를 사용하고, 다음 줄에는 `import`를 사용할 수 있다.
- `import`를 사용하면 다른 패키지의 클래스를 가져와 패키지명을 생략하고 클래스 이름만으로 사용할 수 있다.
특정 패키지에 포함된 모든 클래스를 포함해서 사용하고 싶으면 `import` 시점에 `*(별)`을 사용하면 된다.
클래스 이름 중복
패키지 덕분에 클래스 이름이 같아도 패키지 이름으로 구분해서 같은 이름의 클래스를 사용할 수 있다.
pack.a.User
pack.b.User
- 이런 경우 클래스 이름은 둘 다 `User`이지만 패키지 이름으로 대상을 구분할 수 있다.
package pack;
import pack.a.User;
public class PackageMain3 {
public static void main(String[] args) {
User userA = new User();
pack.b.User userB = new pack.b.User();
}
}
같은 이름의 클래스가 있다면 `import`는 둘 중 하나만 선택할 수 있다. 이때는 자주 사용하는 클래스를 `import`하고 나머지를 패키지를 포함한 전체 경로로 적어주면 된다. 물론 둘 다 전체 경로를 적어준다면 `import`는 사용하지 않아도 된다.
패키지 규칙
패키지 규칙
- 패키지 이름과 위치는 폴더(디렉토리) 위치와 같아야 한다. (필수)
- 패키지 이름은 모두 소문자를 사용한다. (관례)
- 패키지 이름의 앞 부분에는 일반적으로 회사의 도메인 이름을 거꾸로 사용한다. 예를 들어, `com.company.myapp`과 같이 사용한다. (관례)
- 수 많은 외부 라이브러리가 함께 사용되면 같은 패키지에 같은 클래스 이름이 존재할 수도 있다. 이렇게 도메인 이름을 거꾸로 사용한다면 이런 문제를 방지할 수 있다.
- 오픈 소스나 라이브러리를 만들어서 외부에 제공한다면 꼭 지키는 것이 좋다.
- 내가 만든 애플리케이션을 다른 곳에 공유하지 않고, 직접 배포한다면 보통 문제가 되지 않는다.
패키지와 계층 구조
패키지는 보통 다음과 같이 계층 구조를 이룬다.
- a
- b
- c
이렇게 하면 다음과 같이 총 3개의 패키지가 존재한다.
`a`, `a.b`, `a.c`
계층 구조 상 `a` 패키지 하위에 `a.b`, `a.c` 패키지가 있다.
그런데 이것은 우리 눈에 보기에 계층 구조를 이룰 뿐 `a` 패키지와 `a.b`, `a.c` 패키지는 서로 완전히 다른 패키지이다.
따라서 `a` 패키지의 클래스에서 `a.b` 패키지의 클래스가 필요하면 `import`해서 사용해야 한다. 반대도 마찬가지이다.
'Java' 카테고리의 다른 글
[JUnit] @Parameterized Test (0) | 2024.10.26 |
---|---|
Google Java Style Guide (2) | 2024.10.25 |
[Java/김영한] 생성자 (1) | 2024.09.08 |
[Java/김영한] 객체 지향 프로그래밍 (0) | 2024.09.07 |
[Java/김영한] 기본형과 참조형 (1) | 2024.09.07 |