> For the complete documentation index, see [llms.txt](https://byulseop-til.gitbook.io/sinheeseop_til/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://byulseop-til.gitbook.io/sinheeseop_til/java/101/access_modifiers.md).

# AccessModifiers

#### \*\* 접근 제어자 & 메서드 통한 데이터 제어: 핵심 요약 정리\*\*

### **1. 접근 제어자를 사용하는 이유**

* **데이터 무결성 보장:** 클래스 외부에서 필드(예: `age`, `volume`)에 직접 접근 가능하면 잘못된 값이 들어갈 수 있음.
* **유효성 검사 가능:** 필드를 `private`으로 두고 메서드(`setAge()`, `volumeUp()` 등)를 통해 값을 변경하게 하면, 그 안에서 유효성 검사를 수행할 수 있어 **안전한 값 변경**이 보장됨.
* **유지보수성 향상:** 전체 코드 곳곳에서 직접 필드를 변경하면 로직 수정 시 모든 부분을 찾아 고쳐야 하지만, **메서드를 통해 변경하면 해당 메서드만 수정하면 됨**.
* **코드 일관성 유지:** 필드를 직접 수정하는 대신, 동일한 메서드를 사용해 값이 변경되므로 **개발자마다 다른 방식으로 로직이 분산되는 것을 막을 수 있음**.
* **객체 내부 보호(정보 은닉):** `private` 필드를 외부에서 임의로 수정할 수 없게 하여, **객체가 스스로 상태를 관리하도록 강제**(객체 지향 원칙 준수).

### **2. 접근 제어자 이해**

* 자바에서는 `private`, `default`, `protected`, `public` 네 가지 접근 제어자를 제공하여 **클래스·필드·메서드의 접근 범위를 조절**함.
* 접근 범위는 **`private → default → protected → public`** 순으로 점점 넓어짐.

### **3. 접근 제어자 종류**

| 접근 제어자          | 접근 가능 범위                |
| --------------- | ----------------------- |
| **`private`**   | 같은 클래스 내부에서만 접근 가능      |
| **`default`**   | 같은 패키지 내에서만 접근 가능       |
| **`protected`** | 같은 패키지 + 자식 클래스에서 접근 가능 |
| **`public`**    | 모든 패키지, 모든 클래스에서 접근 가능  |

1. **`private`**
   * 가장 제한적인 접근 제어자. **클래스 내부**에서만 필드/메서드 호출 가능.
   * 필드를 `private`으로 설정하면 외부에서 직접 값을 수정할 수 없고, **메서드를 통해서만 값 변경** 가능.
2. **`default`** (package-private)
   * 접근 제어자를 명시하지 않으면 기본 적용.
   * **동일 패키지**에 속한 클래스에서만 접근 가능.
3. **`protected`**
   * **동일 패키지 + 상속 관계**의 자식 클래스에서만 접근 가능.
   * 주로 상속을 다룰 때 사용.
4. **`public`**
   * 어디서든 접근 가능.
   * 클래스, 필드, 메서드를 **공개하고 싶을 때** 사용.

### **4. 필드·메서드에서의 접근 제어자 사용**

아래 예시는 **필드와 메서드**에서 접근 제어자를 설정하는 예시:

```java
public class Person {
    private String name;    // 외부에서 직접 접근 불가
    int age;                // default 접근, 같은 패키지 내에서만 사용 가능

    public Person(String name, int age) {  // public 생성자
        this.name = name;
        this.age = age;
    }

    public void sayHello() {  // public 메서드, 외부에서 호출 가능
        System.out.println("Hello, I'm " + name + ", age " + age);
    }

    private void secretMethod() { // private 메서드, 내부에서만 사용
        System.out.println("비밀 메서드 실행");
    }
}
```

1. **필드(변수)**
   * 보통 **`private`** → 외부에서 함부로 값을 바꾸지 못하도록 하여 **데이터 보호**.
2. **메서드**
   * 외부에서 호출해야 하는 **공개 기능**은 `public`.
   * 내부에서만 사용하는 **도우미 메서드**는 `private`으로 숨겨 캡슐화.
   * 같은 패키지에서만 공유해야 하는 경우 `default` 사용.
3. **클래스 레벨 접근 제어자**
   * **`public` 클래스**: 어디서든 인스턴스 생성 가능.
   * **`default` 클래스**: 같은 패키지 내에서만 사용 가능. (파일명·클래스명 일치 규칙은 `public` 클래스에만 적용)

### **5. 메서드를 통한 데이터 제어의 이점**

아래 예시는 **유효성 검사**를 통해 **잘못된 금액**이 들어가지 않도록 하는 코드입니다:

```java
public class BankAccount {
    private int balance;

    public void deposit(int amount) {
        if (amount < 0) { // 유효성 검사
            System.out.println("유효하지 않은 금액입니다.");
            return;
        }
        balance += amount;
    }

    public int getBalance() {
        return balance;
    }
}
```

1. **잘못된 값 입력 방지 → 유효성 검사**
   * `private` 필드를 직접 수정하지 못하게 하고, **메서드 안에서 음수·최대값 초과 등 검사**를 수행해 오류를 방지.
2. **유지보수성·확장성 증가**
   * 로직이 바뀔 때 **메서드 내부만 수정**하면 되므로, 외부 코드 수정을 최소화할 수 있음.
3. **코드 일관성**
   * 특정 필드를 변경하는 모든 곳이 **동일한 메서드**를 사용하므로, 로직이 일관되고 추적이 쉬움.
4. **객체 보호(정보 은닉)**
   * 객체 내부 필드가 임의로 바뀌지 않도록 막고, **객체 스스로 상태를 관리**.
5. **객체 지향 원칙 준수**
   * 객체가 자신의 상태와 행동을 책임지므로, **자율성과 일관성**을 유지할 수 있음.

### **6. 캡슐화**

> 캡슐화(Encapsulation)는 **데이터와 그 데이터를 처리하는 메서드를 하나로 묶고, 외부에서의 직접 접근을 제한**하는 객체 지향 프로그래밍의 핵심 개념이다.

* \*\*데이터(필드)\*\*를 가능한 숨기고(`private`), \*\*객체가 제공하는 기능(메서드)\*\*을 통해서만 접근하도록 유도.
* 굳이 알 필요가 없는 내부 기능(메서드)은 `private`으로 감추고, \*\*외부에서 꼭 필요한 기능만 `public`\*\*으로 노출.
* **접근 제어자**는 캡슐화를 안전하게 완성하기 위한 핵심 장치:
  1. **데이터를 숨겨라**
     * 외부가 내부 로직을 무시하고 직접 필드에 접근하면, 100 넘으면 안 되는 음량을 200으로 바꾼다든지 하는 문제가 발생.
     * 자동차, 음악 플레이어 예시처럼, 우리는 내부 전원부나 볼륨 데이터 자체를 직접 건드리지 않고 **버튼(메서드)만 사용**하는 것이 바람직.
  2. **기능을 숨겨라**
     * 외부가 사용할 필요가 없는 내부 엔진 로직, 세부 처리 과정을 모두 공개하면 복잡도만 증가.
     * \*\*꼭 필요한 기능만 `public`\*\*으로 제공하고, 나머지는 `private`으로 감춰 사용자가 더 쉽게 사용할 수 있도록 함.

#### **간단 코드 예시**

```java
public class Speaker {
    private int volume; // 1. 데이터 숨김

    public Speaker(int volume) {
        this.volume = volume <= 100 ? volume : 100;
    }

    public void volumeUp() { // 2. 꼭 필요한 기능만 공개
        if (volume < 100) {
            volume += 10;
        }
    }

    private void internalDiagnostics() { // 2. 기능 숨김
        System.out.println("내부 엔진 점검 중...");
    }
}
```

* `volume`은 `private`으로 설정.
* 외부에서 음량을 조절할 때는 오직 `volumeUp()`(or `volumeDown()`) 같은 메서드를 통해서만 가능.
* `internalDiagnostics()`처럼 내부에서만 필요한 기능은 `private`으로 감춰두어 **사용자가 볼 필요가 없음**.

### **7. 정리**

1. **접근 제어자를 활용**하면 필드 값을 보호하고, **잘못된 값 입력**이나 **임의 변경**을 방지할 수 있음.
2. \*\*클래스의 필드는 `private`\*\*으로, **외부에서 필요한 기능만 `public` 메서드를 통해 제공**하는 것이 권장됨.
3. **메서드를 통한 데이터 변경**으로 유효성 검사와 로직 추가가 용이해져 **유지보수성이 높아짐**.
4. **캡슐화를 통해** 데이터와 기능을 하나로 묶어 **객체의 일관성을 유지**하고, 안전하게 보호할 수 있음.
5. 캡슐화 구현의 핵심은 **데이터와 내부 로직은 숨기고, 꼭 필요한 기능만 공개**하며, **접근 제어자**가 이를 가능케 함.

**결론:**

> **필드를 직접 수정하지 않고 메서드를 통해 조작함으로써, 데이터 무결성과 안전성을 높이고**\
> **객체 지향의 캡슐화 원칙을 충실히 구현할 수 있다.**
