Java 파트6-6. 패키지와 접근 제한자

1. 패키지


  • 패키지의 물리적인 형태는 파일 시스템의 폴더
  • 패키지는 클래스의 일부분으로, 클래스를 유일하게 만들어주는 식별자 역할
  • 클래스 이름이 동일하더라도 패키지가 다르면 다른 클래스로 인식
  • 클래스의 전체 이름은 패키지 + 클래스 사용해서 다음과 같이 표현
    • 상위패키지.하위패키지.클래스
    • com.mycompany.A
    • com.yourcompany.B

그림1

2. 패키지 선언


클래스 작성 시 해당 클래스가 어떤 패키지에 속할 것인지를 선언

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

package com.mycompany;

이름 규칙

  • 숫자로 시작 불가
  • _ 와 $를 제외한 특수문자 사용 불가
  • java로 시작하는 패키지는 자바 표준 API에서만 사용하므로 사용 불가
  • 모두 소문자로 작성하는 것이 관례

import문

  • 사용하고자 하는 클래스 또는 인터페이스가 다른 패키지에 소속된 경우 해당 패키지 클래스 또는 인터페이스를 가져와 사용할 것임을 컴파일러에 통지
  • 패키지 선언과 클래스 선언 사이에 작성
  • *는 모든 하위패키지가 import 되는 것이 아니고 해당 패키지의 바로 아래에 해당하는 클래스와 인터페이스만 import 된다. 만약 해당 패키지에 하위 패키지가 있다면 하위 패키지는 import되지 않는다. 따라서 따로 import해줘야 한다.
  • 다른 패키지에 동일한 이름의 클래스가 있는 경우 import와 상관없이 클래스 전체 이름을 기술
import 상위패키지.하위패키지.클래스이름;
import 상위패키지.하위패키지.*; // *는 전체를 의미

// 예시
package com.mycompany; // 현재 패키지 선언

// 패키지와 클래스 선언 사이에 가져올 패키지 선언
import com.hankook.Tire; // com.hankook 패키지에 있는 클래스를 쓰겠다.

public class Car{
    Tire tire = new Tire() // 가져온 클래스 사용
}


// * 예시
import com.hankook.*; // hankook 폴더 안에 있는 클래스와 인터페이스만 import
// hankook 폴더 안에 project 폴더(패키지)가 있다면 위에 코드에서는 이것을 import하지 않으므로 
// 아래와 같이 다시 import 해줘야 함

import com.hankook.project.*; 

// 다른 패키지에 동일한 이름의 클래스가 있는 경우
// kumho와 hankook 패키지에 이름이 동일한 Tire 클래스가 있는 경우
// import와 관계없이 풀네임을 기술한다.
sec06.exam02.kumho.Tire tire1 = new sec06.exam02.kumho.Tire();
sec06.exam02.hankook.Tire tire2 = new sec06.exam02.hankook.Tire();


3. 접근 제한자


클래스와 인터페이스 및 이들이 가진 멤버의 접근 제한

  • public 접근 제한자 : 외부 클래스가 자유롭게 사용할 수 있도록 함
    • public이 붙은 것은 다른 패키지에서 사용 가능하지만 사용전에 import 해줘야함
    • 같은 패키지 내에서는 import할 필요 없음
  • private 접근 제한자 : 외부에서 사용할 수 없도록 함
  • default 접근 제한 : 같은 패키지에 소속된 클래스에서만 사용할 수 있도록 함
    • 일반적으로 아무것도 붙이지 않은 것을 의미함
    • 같은 패키지 내이므로 import할 필요 없음
  • protected 접근 제한자 : 같은 패키지 또는 자식 클래스에서 사용할 수 있도록 함

그림2

클래스의 접근 제한

같은 패키지 내에서만 사용할 것인지 다른 패키지 내에서도 사용할 수 있도록 할 것인지 결정

그림3

다른 패키지에서도 사용하려면 public을 사용해야 하고 다른 패키지에서 사용하지 않으려면 public을 안 붙여도 된다. public을 붙이지 않은 것이 default로 접근 제한 한 것이다.

package sec06.exam03.package1;

public class A {

}

package sec06.exam03.package2;

// A는 다른 패키지에 있으므로 
// import sec06.exam03.package1.A; 가 필요함
public class C {
	A field;
}

package1에서 클래스 A는 public 접근 제한자가 붙어 있으므로 외부 클래스가 자유롭게 사용할 수 있다. 따라서 package2에서 클래스 A를 사용하려면 import 해줘야 하는데 일일이 작성하기 불편하다. 이클립스는 이에 대해 편의 기능을 제공한다. ctrl + shft + O 를 누르면 자동으로 import해준다.
만약 클래스 A와 C가 같은 패키지에 있다면 import를 할 필요가 없다.

생성자의 접근 제한

public class ClassName {
	// 해당 생성자를 이용하여 어디서든 객체를 만들 수 있다.
	public ClassName() {} 
	
	// 같은 패키지 내에서만 생성자를 사용하여 객체를 만들 수 있다.
	ClassName() {}
	
	// 이 클래스 내부에서만 생성자를 이용해서 객체를 만들 수 있다.
	private ClassName() {}	
}

필드와 메소드의 접근 제한

// 필드 선언 // []는 생략해도 된다는 것을 의미하는 것으로 해석
[public | protected | private | default(생략)] [static] 타입 필드;

// 메소드 선언 // []는 생략해도 된다는 것을 의미하는 것으로 해석
[public | protected | private | default(생략)] [static] 리턴타입 메소드(...) {}


4. Getter와 Setter 메소드


클래스 작성 시 별다른 조건이 없다면 모든 필드는 private 으로 선언한다. 외부에서 객체에 마음대로 접근할 경우 객체의 무결성이 깨질 수 있기 때문이다.

Setter 메소드

  • 외부의 값을 받아 필드의 값을 변경하는 것이 목적
  • 매개값 검증하여 유효한 값만 필드로 저장할 수 있음
  • 보통 set으로 메소드명이 시작

Getter 메소드

  • 외부로 필드값을 전달하는 것이 목적
  • 필드값을 가공해서 외부로 전달할 수 있음
  • 보통 get으로 메소드명이 시작
  • boolean 타입의 경우 is로 메소드명이 시작
// 클래스 파일
package sec03.test;

public class Car {
	// 특별한 조건이 없다면 모든 필드는 private으로 선언하여 무결성 보존
	// 초기값은 자동으로 int 0, boolean false로 초기화
	private int speed;
	private boolean stop;
	
	// speed의 값을 가져다 쓸 수 있도록 public 메소드 선언
	public int getSpeed() {
		int km = speed * 3;
		return km;
	}
	
	// speed를 수정할 수 잇도록 public 메소드 선언
	public void setSpeed(int speed) {
		// 유효한 값만 필드로 저장할 수 있도록 조건 설정
		if (speed <0) {
			this.speed =0;
			return;
		} else {
			this.speed = speed;
		}
	}
	
	// boolean Getter은 is로 시작
	public boolean isStop() {
		return stop;
	}
	
	public void setStop(boolean stop) {
		this.stop = stop;
		if(stop) {
			speed =0;
		}
	}
	
	
}


// 메인 클래스 파일
public static void main(String[] args) {
		Car myCar = new Car();
		
		myCar.setSpeed(60);
		System.out.println("현재 속도: " + myCar.getSpeed());
		
		if(!myCar.isStop()) {
			myCar.setStop(true);
		}
		
		System.out.println("현재 속도: " + myCar.getSpeed());
	}

만약 어떤 필드에서 대해서 Getter만 존재한다면 그 필드는 읽기 전용 필드가 되는 것이다. Setter가 없으면 값을 변경할 수가 없기 때문이다.

5. 정리하기


  • 패키지 선언 : 해당 클래스 또는 인터페이스가 어떤 패키지에 속할 것인지 선언
    • package 상위패키지.하위패키지;
  • import 문 : 다른 패키지에 소속하는 클래스와 인터페이스를 사용할 경우 필요
    • import 상위패키지.하위패키지.클래스이름 또는 *;
  • Getter : 필드값을 외부로 리턴하는 메소드 ( getXXX() , isXXX() )
  • Setter : 외부에서 값을 받아 필드값을 변경하는 메소드 ( setXXX() )
  • 접근 제한자 : 클래스, 인터페이스, 그리고 멤버들의 사용을 제한할 경우 사용

그림4


본 포스팅은 ‘혼자 공부하는 자바’를 읽고 공부한 내용을 바탕으로 작성하였습니다.


© 2021. By Backtony