<윤성우의 열혈 Java 프로그래밍> 공부
ch 08. 패키지와 클래스 패스
클래스 패스(Class Path): Java VM이 클래스 파일을 찾는 경로
Current Directory 기준 실행
클래스 패스를 지정하지 않으면, 자바 가상머신은 필요한 클래스들을 현재 디렉토리에서 찾는다. 소스파일이 있는 위치이다. 이 상태에서 몇 클래스 파일들을 다른 디렉토리로 옮기면, main 메소드에서 해당 클래스를 참조할 때 에러가 발생한다. 따라서 이러한 상황이 발생할 때 클래스 패스를 지정할 수 있다.
Class Path 지정
cmd에서
소스파일 위치>set classpath=경로
로 지정할 수 있다. ;으로 둘 이상의 경로를 같이 지정할 수 있다.
소스파일 위치>set classpath=.;경로 (현재 디렉토리와 다른 경로 둘 다 설정)
이때 경로는 절대경로, 상대경로 둘 다 가능하다. 상대경로일 땐 해당 클래스파일이 있는 디렉토리만 \MyClass 식으로 써주면 된다. 실제 개발을 할 땐 상대 경로가 주로 이용된다.
패키지(Package): 클래스의 묶음, 다른 클래스와 구분 짓기 위함
소스파일과 클래스 규칙
- 하나의 소스파일에는 public으로 선언된 클래스의 정의를 하나만 둘 수 있다. (한 소스파일에 여러 클래스를 둘 경우 public없이 정의)
- 소스파일의 이름은 public으로 선언된 클래스의 이름과 동일해야 한다.
위 규칙을 바탕으로, 예를 들어 두 회사에서 사용하는 클래스의 이름이 같은데 둘 다 사용하고 싶을 경우 충돌되어 오류가 발생한다. 이럴 때 패키지로 클래스를 각각 구분 지을 수 있다.
패키지 규칙
- 패키지 이름은 모두 소문자로 작성
- 도메인 이름의 역순으로 구성
- 패키지 이름 끝에 팀을 구분하는 이름 추가
ex) rim.com 회사의 rabo팀에서 개발한 클래스를 묶은 패키지 이름
-> com.rim.rabo
이 패키지의 Test 클래스 인스턴스 생성 방법
-> com.rim.rabo.Test t1 = new com.rim.rabo.Test(814);
클래스를 패키지로 묶을 때는 소스파일 상단에 패키지 선언 추가
-> package com.rim.rabo;
동일한 파일 이름의, 서로 다른 패키지들을 같이 컴파일 하는 경우
-> 소스파일 하위 디렉토리 생성, 다르게 저장
c:\PackageStudy\src\Test1 (com.rim.rabo의 Test class)
c:\PackageStudy\src\Test2 (com.mir.rem의 Test class)
-> 옵션 -d로 패키지 파일 각각 컴파일
c:\PackageStudy>Javac -d . src\Test1\Test.java //-d <현재 디렉토리> <파일이름>
c:\PackageStudy>Javac -d . src\Test2\Test.java
위에 거는 메모장으로 하는 게 더 편한 거 같고,,, 일단 vs에서는 클래스 여러 개를 어떻게 해야 할지 모르겠어서 결국 자바 개발환경으로 유명한 이클립스를 설치했다. 아래처럼 간단하게 packge를 선언해 보았다. (아니 이거 설정 안 하면 파일 생성부터가 안됨.....)

하여튼 이렇게 하면 아래처럼 정말 패키지 이름대로, 자동으로 경로가 생성되어 저장된다.

또한 같은 클래스를 다른 패키지로 구성하여 했을 때, 이클립스에서는 각각 실행시킬 수 있다.
아래는 두 패키지를 인스턴스하여 한번에 실행시킨 결과이다.
//HelloWorld.java
package com.rim.rabo;
public class HelloWorld {
String str;
public HelloWorld(String addStr) {
str = "[" + addStr + "]: " + "Hello world!";
}
public String getStr() {
return str;
}
}
//HelloWorld.java
package com.mir.rem;
public class HelloWorld {
String str;
public HelloWorld(String addStr) {
str = "[" + addStr + "]: " + "Hello world!";
}
public String getStr() {
return str;
}
}
//usingPack.java
public class usingPack {
public static void main(String[] args) {
com.rim.rabo.HelloWorld h1 = new com.rim.rabo.HelloWorld("com.rim.rabo");
com.mir.rem.HelloWorld h2 = new com.mir.rem.HelloWorld("com.mir.rem");
System.out.println(h1.getStr());
System.out.println(h2.getStr());
}
}


추가로, 패키지를 하나만 불러올 땐 import 선언을 하여 이후 코드를 간략화시킬 수 있다.
ex) import com.rim.rabo.*; (*로 하면 해당 패키지 내에 있는 모든 클래스 사용 가능)
HelloWorld h1 = ~; <- 처럼 바로 클래스 이름으로 사용 가능
단, 이 방법은 동일한 클래스 이름이면 이름 충돌 발생 가능, 의도치 않은 인스턴스 문제 등이 있으므로 가급적 사용을 자제하는 것이 좋다.
ch 09. 정보 은닉 & 캡슐화
정보 은닉
- 클래스의 인스턴스 변수를 정보라 하는데, 정보 은닉은 외부에서 변수에 접근을 못하도록(에러 발생 줄이기 위해) 변수 앞에 private를 붙이는 것 등을 말한다.
- private 사용 시, 해당 변수는 그 클래스 내부에서만 참조가 가능하다. 따라서 관례적으로 get, set 메소드를 추가하여 외부에서 참조할 수 있도록 한다.
위와 같이 접근 제한을 두는 선언들을 접근 수준 지시자라고 하며, 4종류가 있다. 위에서부터 아래로 내려갈 수록 접근 범위가 작아진다.
1 public (모든 영역 허용)
- 클래스의 정의: 위치에 상관없이 어디서든 해당 클래스의 객체 생성 가능 / 하나의 소스파일에 크게 하나의 public 클래스만 생성 가능, 그 public 클래스 이름이 소스파일 이름이 되어야 함
- 변수, 메소드: 어디서든 접근 가능
2. protected (클래스 내부, 동일 패키지, 상속받은 클래스 허용)
- 변수, 메소드: default와 비슷하나, 상속관계 시 default는 상속이더라도 다른 패키지면 접근 불가, protected는 상속이면 다른 패키지이더라도 접근 가능
3. default(클래스 내부, 동일 패키지 허용)
- 클래스의 정의: 동일 패키지로 묶인 클래스 내에서만 객체 생성 가능
- 변수, 메소드: 동일 패키지로 묶인 클래스 내에서만 접근 가능
4. private(클래스 내부 허용)
- 변수, 메소드: 해당 클래스 내부에서만 접근 가능
캡슐화
- 해당 클래스와 관련 있는 내용들을 하나의 클래스에 적절히 모두 담는 것을 캡슐화라 한다.
- 한 클래스가 다른 클래스의 객체를 멤버로 가지는 것을 포함 관계라 한다.
문제 09-1 <다양한 클래스의 정의>
Point 클래스를 기반으로 Circle 클래스를 정의하고, main 메소드를 기반으로 Circle 클래스를 테스트한다.
class Point {
int xpos, ypos;
public Point(int x, int y) {
xpos = x;
ypos = y;
}
public void showPointInfo() {
System.out.println("[" + xpos + ", " + ypos + "]");
}
}
class Circle {
int rpos;
Point p1;
public Circle(int x, int y, int r) {
p1 = new Point(x, y);
rpos = r;
}
public void showCircleInfo() {
p1.showPointInfo();
System.out.println("rpos: " + rpos);
}
}
public class useCircle {
public static void main(String[] args) {
Circle c = new Circle(2, 2, 4);
c.showCircleInfo();
}
}
처음엔 Point p1 = new Point(xpos, ypos);로 바로 했었다가 컴파일해 보니 [0, 0]으로 정보가 저장이 안 되는 것을 확인했다. 답안을 참고하니, 먼저 객체를 생성 후 생성자에서 변수를 저장하는 것을 보고 수정하였더니 정상적으로 출력이 되었다.
와 오늘은 이클립스 처음으로 써보면서 자바는 개발환경부터가 어렵군... 을 깨달았다... 특히 public 클래스는 하나만 있어야 된다든가 그거랑 소스파일이랑 이름 같아야 된다든가... c++ 때는 안 그랬던 거 같은데 상당히 까다롭다(아닌가 기억이 안 남) 하여튼 그래도 직접 코드 쳐보니까 더 잘 기억되긴 함
아무튼 오늘도 끝~~!
'✨언어 > Java' 카테고리의 다른 글
| [ch 05, 06, 07] 제어문, 메소드, 클래스 (1) | 2024.06.27 |
|---|---|
| [ch 02, 03, 04] 변수, 상수, 연산자 (0) | 2024.06.26 |
| [ch 01] Java 시작 (1) | 2024.06.25 |