[Java] 23. 접근 제어자
접근 제어자란?
클래스, 변수, 메서드 등에 누가 접근할 수 있는지를 정해주는 키워드입니다.
말 그대로 "이건 누가 볼 수 있고, 누가 못 보게 막을지"를 정하는 키워드입니다.
➡ 캡슐화(정보 은닉)를 구현하는 핵심 도구입니다.
✅ 캡슐화에 관한 자세한 내용은 아래 글을 참고해주세요
[Java] 10. 캡슐화란?
캡슐화란?객체의 속성(데이터)과 메서드(동작)를 하나로 묶고, 외부에서 직접 접근하지 못하도록 감추는 것을 말합니다. 즉, 데이터를 보호하고, 의도하지 않은 결과가 일어나지 않게, 통
development-world.tistory.com
접근 제어자의 종류
자바에는 총 4가지 접근 제어자가 있습니다.
접근 제어자 | 같은 클래스 | 같은 패키지 | 자식 클래스 | 전체 접근 (외부) |
private | ✅ | ❌ | ❌ | ❌ |
(default) | ✅ | ✅ | ❌ | ❌ |
protected | ✅ | ✅ | ✅ | ❌ |
public | ✅ | ✅ | ✅ | ✅ |
private
✅ 가장 강력한 보호 수준!
private은 자바에서 가장 제한적인 접근 제어자입니다.
오직 해당 클래스 내부에서만 사용할 수 있습니다.
외부 클래스, 다른 클래스, 심지어 자식 클래스에서도 직접 접근은 절대 불가❌입니다.
📌 주로 클 클래스의 내부 데이터를 외부에서 함부로 바꾸지 못하게 보호하는 역할을 합니다.
➡ 캡슐화의 핵심
객체 지향 프로그래밍에서는 "데이터를 직접 건드리지 말고, 메서드를 통해 접근해라"는 원칙이 있습니다.
이 원칙을 지키기 위해서 private을 자주 사용합니다.
사용 환경
- 비밀번호처럼 외부에서 건드리면 안 되는 민감한 정보에 사용
- 외부에서는 getPassword()와 같은 메서드로만 접근하도록 만듬
예시
* PrivateExp 클래스
public class PrivateExp {
private String name = "홍길동";
public void printName() {
System.out.println(name); // ⭕ 클래스 내부에서는 접근 가능
}
}
* 실행 클래스
public class PrivateMain {
public static void main(String[] args) {
PrivateExp p = new PrivateExp();
// System.out.println(p.name); // ❌ private이라서 접근 불가
}
}
👉 위에서 p.name을 직접 호출하면 컴파일 에러가 납니다.
대신, printName() 메서드를 통해 간접적으로 접근하는 건 가능합니다.
(default)
✅ 제어자를 안 쓰면 default!
자바에서는 접근 제어자를 아예 안 쓰면, 자동으로 default 접근 제어자가 적용됩니다.
default는 별도로 키워드를 쓰지 않고, 그냥 아무것도 안 썼을 때 적용되는 접근 범위입니다.
아무 접근 제어자도 안 쓰면 default 입니다.
같은 패키지 내에서만 접근 가능, 외부나 상속 관계라도 패키지가 다르면 접근 불가합니다.
👉 default 접근 제어자는 같은 패키지끼리만 볼 수 있습니다.
패키지가 다르면 클래스 자체도 보이지 않습니다!
사용 환경
- 패키지 내에서만 쓰는 도움 메서드
- 라이브러리 내부에서 모듈 간 공유하고 싶지만, 외부에서는 숨기고 싶을 때 사용
예시
💡 패키지 구조
📦 chapter21
└── defaultExp1
└── Tiger.java
└── defaultExp2
└── Zoo.java
* Tiger 클래스 (defaultExp1 패키지)
package chapter21.defaultExp1;
// public 클래스 → 어디서든 보임
public class Tiger {
// default 변수
String name = "호랑이";
// default 메서드
void roar() {
System.out.println("어흥!");
}
}
* Zoo 클래스 (defaultExp2 패키지)
package chapter21.defaultExp2;
import chapter21.defaultExp1.Tiger;
public class Zoo {
public static void main(String[] args) {
Tiger t = new Tiger(); // ⭕ Tiger 클래스는 public이므로 생성 가능
// System.out.println(t.name); // ❌ default 변수는 접근 불가
// t.roar(); // ❌ default 메서드도 접근 불가
}
}
- Tiger 클래스는 public이라 다른 패키지에서도 import 가능합니다.
- name 변수와 roar() 메서드는 default라서 다른 패키지에서는 접근 불가합니다.
✅ 클래스가 public이더라도, 내부 멤버가 default면 다른 패키지에서 접근 불가!
protected
✅ 접근 범위가 중간쯤 되는 제어자!
private보단 넓고, public보단 좁습니다.
✅ 같은 패키지 안에서는 누구든 접근 가능
✅ 패키지가 달라도 자식 클래스라면 접근 가능
❌ 단, 패키지도 다르고 상속 관계도 없으면 접근 불가!
사용 환경
👉 패키지 바깥에 있는 자식 클래스가 부모의 필드나 메서드에 접근할 수 있게 해주는 데 쓰입니다.
- 자식 클래스에서 공통적으로 상속받아 사용하거나, 오버라이딩 해야 하는 기능
- 외부에서는 사용 못하지만, 상속받은 쪽에서는 접근 가능하게 열어두고 싶을 때
예시
* Parent 클래스 (protectedExp1패키지)
package chapter21.protectedExp1;
public class Parent {
protected String name = "부모님";
protected void hello() {
System.out.println("안녕, 나는 부모야!");
}
}
* Child 클래스 (protectedExp2 패키지)
package chapter21.protectedExp2;
import chapter21.protectedExp1.Parent;
public class Child extends Parent {
public void introduce() {
System.out.println("내 부모는: " + name); // ⭕ protected 접근 가능
hello(); // ⭕ 메서드도 호출 가능
}
}
👉 Parent는 다른 패키지지만, Child가 상속받았기 때문에 접근 가능!
❌ 상속받지 않은 클래스는?
package chapter21.protectedExp2;
import chapter21.family.Parent;
public class Stranger {
public void show() {
Parent p = new Parent();
// System.out.println(p.name); // ❌ 에러 발생
// p.hello(); // ❌ 에러 발생
}
}
❌ protected 멤버는 상속받은 클래스가 아니면 외부에서 접근할 수 없습니다!
public
✅ 어디서든 접근 가능!
자바에서 가장 넓은 접근 범위를 갖는 접근 제어자입니다.
"어디서든 접근 가능" 하다는 의미입니다.
- 같은 클래스 ✅
- 같은 패키지 ✅
- 다른 패키지 ✅
- 상속 여부 관계없이 ✅
모든 위치에서 자유롭게 접근할 수 있습니다!
사용 환경
- 많은 곳에서 공통으로 사용해야 하는 클래스나 메서드
- 다른 패키지, 다른 프로젝트에서 접근해야 하는 공개 API
- 라이브러리나 프레임워크에서 외부에 제공하는 기능
💡 즉, 누구나 쓸 수 있어야 하는 기능이라면 public이 필요합니다.
예시
* Person 클래스 (publicExp1 패키지)
package chapter21.publicExp1;
public class Person {
public String name = "홍길동"; // 누구나 접근 가능한 변수
public void introduce() { // 외부에서도 호출 가능한 메서드
System.out.println("안녕하세요, 제 이름은 " + name + "입니다.");
}
}
* 실행 클래스 (publicExp2 패키지)
package chapter21.publicExp2;
import chapter21.publicExp1.Person;
public class PublicMain {
public static void main(String[] args) {
Person p = new Person(); // ✅ 클래스 접근 가능
System.out.println(p.name); // ✅ 변수 접근 가능
p.introduce(); // ✅ 메서드 호출 가능
}
}
- public class → 다른 패키지에서도 이 클래스를 import해서 사용할 수 있음
- public 필드/메서드 → 외부에서 직접 호출 가능
✅ 패키지가 다르더라도 모든 접근이 OK!
바로 이게 public의 특징입니다.
주의사항
클래스가 public이어야 다른 클래스에서 import 가능합니다.
- public이 없는 클래스는 다른 패키지에서 보이지 않음
- 클래스 자체를 공개하려면 반드시 public으로 선언
읽어주셔서 감사합니다 😊