Java 접근제어자 완벽 가이드, public부터 default까지 한 번에 정리!
🔐 객체 지향의 핵심, Java 접근제어자를 완벽하게 이해해보세요!
Java를 배우다 보면 public, private, protected, default와 같은 단어를 자주 접하게 됩니다.
처음에는 생소하게 느껴질 수 있지만, 클래스와 객체 개념을 제대로 이해하려면 이 접근제어자의 의미를 명확히 알아두는 것이 매우 중요합니다.
접근제어자는 단순히 코드를 숨기는 기능을 넘어서, 프로그램의 안정성과 확장성을 높이는 핵심적인 역할을 해줍니다.
이 글에서는 초보자도 이해하기 쉬운 설명과 예제를 통해 Java 접근제어자를 한눈에 정리해드릴게요.
천천히 따라오시면 여러분도 금방 객체 지향의 문을 열 수 있습니다.
Java에서의 접근제어자(Access Modifier)는 클래스, 메서드, 변수 등에 접근 가능한 범위를 설정하여 정보 은닉과 캡슐화를 구현합니다.
이 네 가지 키워드는 객체 지향 프로그래밍의 기본이자, 안정적인 코드 작성의 핵심입니다.
이번 글에서는 각 접근제어자의 정의부터 사용 예시, 그리고 실제 활용 팁까지 모두 다뤄보겠습니다.
이제부터 본격적으로 Java 접근제어자의 세계로 들어가볼까요?
📋 목차
🔗 접근제어자란 무엇인가요?
Java에서 접근제어자(Access Modifier)는 클래스, 메서드, 필드 등의 접근 가능 범위를 지정하는 데 사용됩니다.
이를 통해 외부에서 내부 구현을 직접 접근하지 못하게 막아 정보 은닉(Information Hiding)과 캡슐화(Encapsulation)를 구현할 수 있습니다.
즉, 프로그램의 구조를 보다 견고하게 만들고, 유지보수를 쉽게 하며, 보안을 강화할 수 있게 도와주는 중요한 요소입니다.
Java에는 총 4가지 접근제어자가 존재합니다.
각각의 접근 범위는 다음과 같이 정의됩니다.
- 🌐public : 어디서든 접근 가능
- 🔐private : 같은 클래스 내에서만 접근 가능
- 🛡️protected : 같은 패키지 또는 상속 관계 클래스에서 접근 가능
- 📁default (명시 안함) : 같은 패키지 내에서만 접근 가능
이러한 접근제어자들을 적절하게 활용하면 외부에 공개되어야 할 정보와 그렇지 않은 정보를 명확하게 구분할 수 있게 됩니다.
이것이 바로 객체 지향 프로그래밍에서 캡슐화의 핵심이며, 복잡한 시스템에서도 효율적인 설계를 가능하게 해주는 원리이기도 하죠.
🛡️ public, private의 차이점
Java에서 가장 자주 사용되는 접근제어자는 단연 public과 private입니다.
이 두 키워드는 클래스 또는 멤버가 어디서 접근 가능한지를 결정하며, 잘못 사용할 경우 코드의 안정성을 해칠 수 있기 때문에 정확히 이해하고 사용하는 것이 중요합니다.
🌐 public: 어디서든 접근 가능
public은 가장 개방적인 접근제어자입니다.
프로젝트 내의 어떤 클래스에서든 해당 멤버에 접근할 수 있습니다.
주로 외부에 공개되어야 하는 API, 라이브러리, 인터페이스 등에 사용되며, 진입 지점인 main() 메서드 역시 public으로 선언됩니다.
public class Car {
public String model;
public void drive() {
System.out.println("주행 시작!");
}
}
🔐 private: 클래스 내부에서만 접근 가능
private은 가장 제한적인 접근제어자입니다.
선언된 클래스 내부에서만 해당 멤버에 접근할 수 있으며, 외부 클래스나 서브클래스에서도 접근이 불가능합니다.
이는 정보 은닉을 위한 핵심 키워드이며, 주로 객체의 상태를 직접 변경하지 못하게 보호하는 데 사용됩니다.
public class BankAccount {
private int balance;
public void deposit(int amount) {
balance += amount;
}
public int getBalance() {
return balance;
}
}
이처럼 public은 어디서나 접근이 가능한 반면, private은 오직 자신의 클래스 내에서만 접근이 가능합니다.
따라서 외부에서 직접적으로 속성을 변경하거나 호출하면 안 되는 경우에는 반드시 private으로 선언해야 합니다.
🔒 protected와 default는 어디에 쓰이나요?
Java에서는 public과 private 외에도 protected와 default(명시 없음) 접근제어자가 존재합니다.
이 둘은 주로 패키지 구조와 상속 관계에서 활용되며, 이해하기 어려운 개념처럼 보일 수 있지만 핵심만 알면 의외로 간단합니다.
🛡️ protected: 상속 관계에서 접근 허용
protected는 같은 패키지 내의 클래스 또는 다른 패키지에 있더라도 상속받은 하위 클래스에서는 접근이 가능합니다.
즉, 상속 구조를 활용한 클래스 설계에서 재정의(Override)나 확장(Extend)을 위해 필요한 멤버에 주로 사용됩니다.
class Animal {
protected void makeSound() {
System.out.println("동물이 소리를 낸다");
}
}
class Dog extends Animal {
public void bark() {
makeSound(); // 접근 가능
System.out.println("멍멍!");
}
}
이 예제처럼 protected는 자식 클래스에서 상속받아 사용할 수 있는 안전한 방식을 제공합니다.
하지만 무분별한 사용은 오히려 캡슐화를 해칠 수 있으므로 필요한 경우에만 사용하는 것이 좋습니다.
📁 default: 같은 패키지 내에서만 접근 가능
접근제어자를 따로 명시하지 않으면 Java는 해당 멤버에 default 접근제어자를 자동으로 적용합니다.
이 경우 해당 멤버는 같은 패키지 내부에서만 접근 가능하며, 패키지가 다른 클래스에서는 접근이 불가능합니다.
class PackageExample {
void printInfo() {
System.out.println("패키지 내부에서만 접근 가능");
}
}
default는 간단한 유틸리티 클래스나 패키지 내 협력 클래스에서 자주 사용됩니다.
다만, 접근 범위가 불명확해지는 경우가 있으니 명시적인 접근제어자 사용을 권장하는 개발자도 많습니다.
🧱 정보 은닉과 캡슐화의 원리
객체지향 프로그래밍에서 정보 은닉(Information Hiding)은 가장 기본적인 원칙 중 하나입니다.
이는 객체 내부의 상태나 구현 세부사항을 외부에 노출하지 않고, 오직 필요한 인터페이스만 공개함으로써 소프트웨어의 안정성을 확보하는 개념입니다.
접근제어자는 바로 이 정보 은닉을 실현하는 도구입니다.
변수를 private으로 감싸고, 외부에서는 메서드를 통해서만 상태를 읽거나 수정하도록 제한함으로써, 내부 로직의 보호와 오류 가능성을 줄일 수 있습니다.
💎 핵심 포인트:
접근제어자를 통해 외부로부터 데이터를 보호하고, 객체 내부 구조를 유연하게 변경할 수 있는 여지를 남겨둡니다.
📦 캡슐화란 무엇인가요?
캡슐화(Encapsulation)는 데이터와 메서드를 하나로 묶고 외부에서는 그 내부 구조를 알 수 없도록 숨기는 설계 방식입니다.
이 구조 덕분에 개발자는 클래스 내부 구현을 자유롭게 수정할 수 있고, 사용자 입장에서는 기능만 신뢰하고 사용할 수 있습니다.
public class User {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
이렇게 private 변수 + public 메서드 조합은 캡슐화의 전형적인 예입니다.
변수에 직접 접근하지 않고, 메서드를 통해 제한적으로 값을 설정하고 가져올 수 있어, 잘못된 입력이나 예외 상황에 대응하기 용이합니다.
접근제어자는 단순한 문법 요소를 넘어서, 설계 철학과 유지보수 전략의 핵심입니다.
이러한 구조를 잘 활용하면 더 견고하고 유연한 프로그램을 만들 수 있습니다.
💡 접근제어자 선택 팁과 실전 예제
Java에서 접근제어자를 언제, 어떻게 선택할지는 개발자의 설계 의도와 코드 안정성에 큰 영향을 줍니다.
아무 제어자나 사용하는 것이 아니라, 구조적인 사고와 사용 목적에 따라 적절한 범위를 선택하는 것이 중요합니다.
- 🔐객체 내부 데이터 보호 → private 사용
- 🌐어디서든 접근 필요한 메서드 → public 사용
- 🛡️상속 구조에서 내부 공유 → protected 사용
- 📁패키지 내부에서만 필요 → default 사용
📘 실전 예제: 사용자 클래스 설계
아래 예제는 다양한 접근제어자가 실제로 어떻게 함께 사용되는지를 보여줍니다.
목표는 사용자 정보를 안전하게 관리하면서, 외부에서는 필요한 기능만 접근 가능하도록 하는 것입니다.
public class User {
private String id; // 외부 접근 차단
private String password; // 외부 접근 차단
public User(String id, String password) {
this.id = id;
this.password = password;
}
public boolean login(String inputPw) {
return password.equals(inputPw);
}
protected void resetPassword(String newPw) {
this.password = newPw;
}
void printUserInfo() {
System.out.println("ID: " + id);
}
}
이 예제에서 핵심 데이터는 private으로 은닉하고, 외부에서는 public 메서드를 통해 로그인만 허용합니다.
패키지 내에서만 쓸 메서드는 default로, 상속 후 비밀번호 초기화를 가능케 하는 기능은 protected로 선언되어 있습니다.
이처럼 상황에 맞는 접근제어자 활용은 클래스를 안전하고 명확하게 만듭니다.
❓ 자주 묻는 질문 (FAQ)
접근제어자가 꼭 필요한 이유는 무엇인가요?
default 접근제어자는 어떻게 쓰이나요?
protected는 상속 외에도 쓸 수 있나요?
getter, setter를 꼭 만들어야 하나요?
모든 메서드를 public으로 만들면 안 되나요?
접근제어자는 클래스에도 사용할 수 있나요?
접근제어자는 인터페이스에서도 쓰이나요?
캡슐화와 접근제어자는 무슨 관계인가요?
🚀 Java 접근제어자, 객체 지향의 핵심을 이해하다
Java의 접근제어자는 단순한 문법 요소가 아닙니다.
코드의 보안성과 구조를 잡아주는 가장 기본이자 중요한 기능입니다.
public, private, protected, default 각 키워드의 접근 범위와 쓰임새를 명확히 이해하면, 어떤 기능을 외부에 노출하고 어떤 정보는 은닉해야 하는지 스스로 판단할 수 있게 됩니다.
또한 정보 은닉과 캡슐화의 개념을 실천하는 데에도 핵심적인 역할을 하죠.
객체 지향 프로그래밍을 처음 접하는 분들에게는 약간 까다로울 수 있지만, 이 글에서 다룬 개념과 예제를 반복해서 익힌다면 접근제어자에 대한 감각이 자연스럽게 생길 것입니다.
앞으로 더 견고하고 확장 가능한 Java 프로그램을 작성하기 위해, 이 핵심 원리를 꼭 기억해두세요!
🏷️ 관련 태그 : Java접근제어자, public private 차이, protected default, Java캡슐화, 정보은닉, 객체지향설계, 접근제어자정리, 자바입문, Java코딩팁, Java클래스