Java - 접근 제어자

develkkm·2025년 9월 12일

0부터 시작하는 Java

목록 보기
15/27

접근 제어자 (Access Modifier)


접근 제어자가 필요한 이유

자바는 public, private 같은 접근 제어자(access modifier)를 제공한다.
이를 통해 클래스 외부에서 특정 필드나 메서드에 접근하는 것을 허용하거나 제한할 수 있다.

예를 들어, 스피커의 음량은 절대 100을 넘으면 안된다는 요구사항이 있다고 해보자.

package access;

public class Speaker {
    int volume;

    Speaker(int volume) {
        this.volume = volume;
    }

    void volumeUp() {
        if (volume >= 100) {
            System.out.println("음량을 증가할 수 없습니다. 최대 음량입니다.");
        } else {
            volume += 10;
            System.out.println("음량을 10 증가합니다.");
        }
    }

    void showVolume() {
        System.out.println("현재 음량:" + volume);
    }
}

이 코드는 정상 동작한다. 하지만 다른 개발자가 speaker.volume = 200;과 같이 필드를 직접 수정하면 제약이 깨진다.
따라서 데이터를 외부로부터 안전하게 보호할 수 있는 장치가 필요하다.


접근 제어자 종류

자바는 4가지 접근 제어자를 제공한다.

  • private : 모든 외부 호출 차단 (클래스 내부에서만 접근 가능)
  • default (package-private) : 같은 패키지 안에서만 접근 가능
  • protected : 같은 패키지 + 상속 관계에서는 접근 가능
  • public : 모든 외부 접근 허용

제한 수준은 다음과 같다:
private < default < protected < public


접근 제어자와 캡슐화

캡슐화(Encapsulation)는 객체 지향 프로그래밍의 중요한 개념이다.
데이터와 해당 데이터를 처리하는 기능을 하나로 묶고, 불필요한 부분을 숨겨 외부 접근을 제한하는 것이다.

데이터를 숨겨야 하는 이유

  • 외부에서 필드에 직접 접근하면 내부 로직을 무시할 수 있다.
  • 예: Speakervolume을 외부에서 200으로 바꾸면 내부 제약이 깨진다.
  • 따라서 필드는 보통 private으로 두고, 대신 getter / setter 혹은 적절한 메서드를 제공한다.

기능을 숨겨야 하는 이유

  • 내부에서만 필요한 기능까지 외부에 노출하면 사용자는 혼란스러워진다.
  • 꼭 필요한 기능만 public으로 노출하고, 나머지는 private으로 감춘다.

필드와 메서드에서의 사용

예시: AccessData 클래스

package access.a;

public class AccessData {
    public int publicField;
    int defaultField;
    private int privateField;

    public void publicMethod() { ... }
    void defaultMethod() { ... }
    private void privateMethod() { ... }

    public void innerAccess() {
        publicField = 100;
        defaultField = 200;
        privateField = 300;
        publicMethod();
        defaultMethod();
        privateMethod();
    }
}
  • public : 어디서든 접근 가능
  • default : 같은 패키지에서만 접근 가능
  • private : 클래스 내부에서만 접근 가능
  • 내부 메서드(innerAccess)에서는 자기 자신이므로 모두 접근 가능

클래스 레벨 접근 제어자

클래스에는 public, default만 사용할 수 있다.

package access.a;

public class PublicClass { } // 어디서든 접근 가능
class DefaultClass1 { }      // 같은 패키지에서만 접근 가능
class DefaultClass2 { }
  • public 클래스는 파일 이름과 동일해야 하며, 한 파일에 하나만 존재할 수 있다.
  • default 클래스는 같은 파일에 여러 개 작성 가능하다.

캡슐화 예제: BankAccount

package access;

public class BankAccount {
    private int balance;

    public void deposit(int amount) {
        if (isAmountValid(amount)) {
            balance += amount;
        }
    }

    public void withdraw(int amount) {
        if (isAmountValid(amount) && balance - amount >= 0) {
            balance -= amount;
        }
    }

    public int getBalance() {
        return balance;
    }

    private boolean isAmountValid(int amount) {
        return amount > 0;
    }
}
  • balance: 외부에서 직접 접근 불가 (private)
  • deposit, withdraw, getBalance: 외부에 공개 (public)
  • isAmountValid: 내부 검증 용도로만 사용 (private)

→ 외부 사용자는 3개의 메서드만 알면 되고, 나머지는 내부에서 안전하게 처리된다.

profile
알던것을 더 확실하게

0개의 댓글