9장. 자바를 배우면 패키지와 접근 제어자는 꼭 알아야 해요

공부하는 감자·2023년 11월 30일
0

자바의 신 3판

목록 보기
9/30

들어가기 전

『자바의 신 3판』 을 읽고 내용 정리 및 공부한 내용을 정리한 글입니다.
서적: 자바의 신 3판 구입처

내용 정리

패키지 Package

클래스들을 구분 짓는 폴더와 비슷한 개념이다. 자바 애플리케이션을 개발할 때 클래스들을 분류하지 않으면 이름이 중복되거나, 어떤 클래스가 어떤 일을 하는지 혼동되는 일이 발생한다. 그래서 존재하는 것이 바로 “패키지”다.

package c.javapackage;
public class Package {
    public static void main(String[] args) {
        System.out.println("Package class.");
    }
}

package 라는 예약어를 쓰고, c/javapackage라는 폴더 안에 있다면 점(.)으로 경로를 구분하여 c.javapackage라고 적어주면된다.

패키지의 제약사항

  • 소스의 가장 첫 줄에 있어야만 한다.
    • package 선언 위에 주석이나 공백은 있어도 되는데, 다른 자바 문장이 하나라도 있으면 컴파일이 제대로 되지 않는다.
  • 패키지 선언은 소스 하나에는 하나만 있어야 한다.
    • 한 소스 파일이 두 개의 폴더에 한 번에 존재할 수 없기 때문이다.
  • 패키지 이름과 위치한 폴더 이름이 같아야 한다.
    • 만약 다를 경우, javac로 컴파일하려고 하면 파일을 찾지 못해 컴파일이 되지 않는다.
  • 패키지 이름은 java로 시작해서는 안된다.
    • SecurityException: Prohibited name: java
    • Oracle에서 사용하는 패키지 이름이다.

패키지 이름 규칙

패키지 시작 이름내용
java자바 기본 패키지 (Java 벤더에서 개발)
javax자바 확장 패키지 (Java 벤더에서 개발)
org일반적으로 비 영리단체(오픈 소스)의 패키지
com일반적으로 영리단체(회사)의 패키지

가장 대표적인 오픈소스 그룹인 아파치의 코드들이 모두 org.apache로 시작한다.

패키지 이름 유의사항

  • 패키지의 이름은 모두 소문자로 지정해야 한다.
    • 반드시는 아니지만 소문자로 사용하기로 약속되어 있다.
  • 자바의 예약어를 사용하면 절대 안된다.

import

자바에서는 패키지가 있을 때, 같은 패키지에 있는 클래스들과 java.lang 패키지에 있는 클래스들만 찾을 수 있다.

다른 패키지에 있는 클래스에 접근할 때 import 를 사용한다.

// c\javapackage\sub 폴더
package c.javapackage.sub;
public class Sub {
    public Sub() {
    }
    public void subClassMethod() {
    }
}

// c\javapackage 폴더
package c.javapackage;
import c.javapackage.sub.Sub;
public class Package {
    public static void main(String[] args) {
        Sub sub=new Sub();
        sub.subClassMethod();
    }
}

import 단어 뒤에 “패키지이름.클래스이름”을 명시해 주면 그 패키지에 있는 클래스를 사용하겠다는 것을 컴파일러에게 알려주는 것이다.

그러면, 컴파일러는 Sub라는 클래스가 c.javapackage.sub에 있다는 것을 알고 컴파일을 해준다.

만약 Sub 클래스가 컴파일 되지 않았더라도, 해당 경로에 관련 클래스의 Java 파일이 존재하면 그 클래스를 먼저 컴파일한 후 호출하는 클래스를 컴파일한다.

💡 javac 컴파일 시 같은 패키지 내의 파일을 찾지 못해 오류가 나는 현상이 있었다.
error: cannot find symbol: class ParentOverriding
이 경우, 아래와 같이 컴파일 한다. 점(.)은 현재 경로를 말한다.
$ javac -cp . {클래스}.java
자바 실행 시
$ java -classpath . {클래스}

import *

package c.javapackage.sub.*;

특정 폴더 아래의 모든 클래스를 import 한다. 단, 그 패키지에 선언된 클래스만 import 하고, 그 하위 패키지에 선언된 클래스들은 import 하지 않는다.

import static

JDK 5부터는 import static이라는 것이 추가되었다.

static 변수에 접근하거나 static 메소드를 사용할 때, 만약 import static이 없다면 클래스명.Static메소드명(); 처럼 사용해야 한다.

하지만, import static으로 static한 변수나 메소드를 지정하면 굳이 클래스 이름을 지정하지 않아도 사용할 수 있다.

import static c.javapackage.sub.클래스명.Static메소드명;
import static c.javapackage.sub.클래스명.Static변수명;

public static void main(String[] args) {
	Static메소드명();
	System.out.println(Static변수명);
}

여러 줄로 쓰기 귀찮으면 *를 사용해도 된다.

import static c.javapackage.sub.클래스명.*;

만약 Package 클래스에 import한 동일한 이름의 static 변수나 static 메소드가 자신의 클래스에 있다면?

static 메소드나 변수가 중복되는 상황에서는 자신의 클래스에 있는 static 변수나 메소드가 우선이다.

import를 하지 않아도 되는 패키지

  • java.lang 패키지
    • String과 System 이라는 클래스가 모두 이 패키지에 속한다.
  • 같은 패키지

접근 제어자 Accesss modifier

자바의 접근 제어자에는 4개가 있다. 이 접근 제어자는 클래스, 메소드, 인스턴스 및 클래스 변수를 선언할 때 사용된다.

다른 사람들이 그 메소드나 변수를 마음대로 호출하거나 변경하지 못하도록 할 때 사용한다.

변수를 private하게 선언하고 메소드에서만 변경 및 조회가 가능하도록 만들면, 생성자로만 변수의 값을 선언할 수 있고 아무도 그 값을 변경하지 못할 것이다.

접근할 수 있는 권한

해당 클래스같은 패키지상속 받은 클래스import한 클래스
publicOOOO
protectedOOOX
package-privateOOXX
privateOXXx

package-private은 아무런 접근 제어자를 적어주지 않을 때(default)에 해당하며, package라고 적기도 한다.

접근 제어자 선언할 때 유의점

접근 제어자는 메소드, 인스턴스 변수, 클래스 변수에도 동일하게 적용할 수 있다. 이 외에 클래스 선언문에도 사용이 가능하다.

자바에서는 하나의 클래스 소스에 여러 개의 클래스를 선언해도 상관 없다. 하지만 public으로 선언된 클래스가 소스 내에 있다면, 그 소스 파일의 이름은 public인 클래스 이름과 동일해야만 한다.

정리해 봅시다.

Q. 패키지를 선언할 때 사용하는 예약어는 무엇인가요?

Me: package

Q. 패키지 선언은 클래스 소스 중 어디에 위치해야 하나요?

Me: 소스 코드 맨 위에

Q. 패키지를 선언할 때 가장 상위 패키지의 이름으로 절대 사용하면 안되는 단어는 무엇인가요?

Me: java

Q. 패키지 이름에 예약어가 포함되어도 되나요?

Me: 아니오

Q. import는 클래스 내에 선언해도 되나요?

Me: 아니오

Q. 같은 패키지에 있는 클래스를 사용할 때 import를 해야 하나요?

Me: 아니오

Q. 특정 패키지에 있는 클래스들을 모두 import할 때 사용하는 기호는 무엇인가요?

Me: *

Q. 클래스에 선언되어 있는 static한 메소드나 변수를 import하려면 어떻게 선언해야 하나요?

Me: import static 경로.메소드 or 경로.변수

Q. 접근 제어자 중 가장 접근 권한이 넓은 (어떤 클래스에서도 접근할 수 있는) 것은 무엇인가요?

Me: public

Q. 접근 제어자 중 가장 접근 권한이 좁은 (다른 클래스에서는 접근할 수 없는) 것은 무엇인가요?

Q. 접근 제어자 중 같은 패키지와 상속관계에 있는 클래스만 접근할 수 있도록 제한하는 것은 무엇인가요?

Me: protected

Q. Calculate.java라는 자바 소스가 있을 경우, 그 소스 내에는 Calculate라는 클래스외에는 (     )으로 선언된 클래스가 있으면 안된다. 여기서 괄호 안에 들어가야 하는 것은 무엇인가요?

Me: public

profile
책을 읽거나 강의를 들으며 공부한 내용을 정리합니다. 가끔 개발하는데 있었던 이슈도 올립니다.

0개의 댓글