1. Java 접근 제어자 요약
Java에서는 접근 제어자를 통해 클래스, 변수, 메서드 등의 접근 범위를 지정할 수 있습니다. 이를 통해 코드의 캡슐화를 유지하고, 외부에서 불필요한 접근을 제한할 수 있습니다.
1.1 접근 제어자 비교 표
접근 제어자 | 같은 클래스 | 같은 패키지 | 하위 클래스 (같은 패키지) | 하위 클래스 (다른 패키지) | 다른 클래스 |
---|---|---|---|---|---|
public |
✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
protected |
✔️ | ✔️ | ✔️ | ✔️ | ❌ |
package-private (기본값) |
✔️ | ✔️ | ✔️ | ❌ | ❌ |
private |
✔️ | ❌ | ❌ | ❌ | ❌ |
✔️: 접근 가능
❌: 접근 불가
2. Java 접근 제어자 자세히 설명
2.1 public
: 모든 클래스에서 접근 가능
특징
- 가장 넓은 접근 범위를 가지며, 프로젝트 내 모든 클래스에서 접근할 수 있습니다.
- 주로 공용 API나 외부와 상호작용이 필요한 메서드, 변수에 사용됩니다.
사용 예시
public class PublicExample {
public String message = "Hello, World!";
public void printMessage() {
System.out.println(message);
}
}
사용 상황
- 라이브러리 또는 프레임워크 개발 시: 외부에서 호출될 메서드와 클래스는
public
으로 선언. - 공유 메서드: 모든 클래스에서 접근 가능한 유틸리티 메서드 (e.g.,
Math.max()
).
2.2 protected
: 같은 패키지와 하위 클래스에서 접근 가능
특징
- 같은 패키지에 있는 클래스와 다른 패키지에 있는 하위 클래스에서도 접근 가능합니다.
- 주로 상속 관계에서 부모 클래스의 필드와 메서드를 자식 클래스에서 재사용할 때 사용됩니다.
사용 예시
class Parent {
protected String name = "Parent";
protected void displayName() {
System.out.println(name);
}
}
class Child extends Parent {
public void callParentMethod() {
displayName(); // 부모 클래스의 protected 메서드 호출 가능
}
}
사용 상황
- 상속을 통해 확장 가능성을 고려한 클래스 설계.
- 외부 접근을 막으면서도 하위 클래스에 제한된 권한 부여.
2.3 package-private
(기본값): 같은 패키지에서만 접근 가능
특징
- 접근 제어자를 명시하지 않을 경우 기본값으로 설정됩니다.
- 같은 패키지 내에서만 접근할 수 있으며, 다른 패키지나 하위 클래스에서는 접근이 불가능합니다.
사용 예시
class PackagePrivateExample {
int defaultNumber = 42; // package-private
void printNumber() {
System.out.println(defaultNumber);
}
}
사용 상황
- 패키지 내부에서만 사용되는 클래스나 헬퍼 메서드에 적합.
- 외부 노출이 필요하지 않은 경우, 불필요한 접근을 막을 수 있음.
2.4 private
: 같은 클래스에서만 접근 가능
특징
- 클래스 내부에서만 접근 가능하며, 가장 제한적인 접근 제어자입니다.
- 변수나 메서드의 캡슐화를 유지하기 위해 사용됩니다.
사용 예시
class PrivateExample {
private int secretNumber = 12345; // private 변수
private void printSecret() {
System.out.println(secretNumber);
}
public void accessSecret() {
printSecret(); // 클래스 내부에서만 접근 가능
}
}
사용 상황
- 클래스 내부 구현을 숨기고, 외부로부터의 의도하지 않은 변경을 방지.
- 보안 및 코드 안정성을 높이기 위해 내부 데이터 보호.
3. Java 접근 제어자 선택 기준
3.1 설계 원칙
- **최소 권한 원칙 (Principle of Least Privilege)**을 준수하여 최소한의 접근 범위만 부여.
- 코드의 재사용성과 확장성을 고려하여 적절한 접근 제어자 설정.
3.2 접근 제어자 선택 방법
private
로 시작: 기본적으로 모든 변수와 메서드는private
으로 설정.protected
로 확장: 상속 관계에서 하위 클래스에 권한이 필요한 경우.package-private
로 설정: 같은 패키지 내에서만 사용되는 기능.public
으로 노출: 외부 API나 필수적인 공용 메서드.
4. Java 접근 제어자 FAQ
Q1. protected
와 package-private
의 차이는?
protected
: 같은 패키지뿐 아니라 다른 패키지의 하위 클래스에서도 접근 가능.package-private
: 같은 패키지 내에서만 접근 가능.
Q2. 언제 private
만 사용해야 하나요?
- 클래스 내부 데이터가 외부 변경으로 인해 오류를 일으킬 가능성이 있을 때.
- 예: 비밀번호, 민감한 데이터, 내부 계산 로직.
Q3. public
으로 모든 것을 선언하면 안 되나요?
- 모든 것을
public
으로 선언하면 캡슐화가 깨지고, 유지보수가 어려워짐. - 인터페이스로 노출할 부분만
public
으로 지정.
5. 결론
Java의 접근 제어자는 코드의 안정성, 보안, 유지보수성을 높이기 위해 매우 중요합니다.
다음 원칙을 기억하세요:
private
로 시작하여 점진적으로 접근 범위를 확장.- 필요한 경우에만
protected
와public
으로 변경. - 캡슐화와 최소 권한 원칙을 준수.
적절한 접근 제어자를 사용하면 유지보수 비용을 줄이고, 코드 품질을 높일 수 있습니다.