인프런/김영한 자바

[김영한의 실전 자바 기본편] - 6. 접근 제어자

sson-coding 2025. 9. 9. 14:25
본 글은 김영한 님의 『김영한의 실전 자바 - 기본편』 강의를 학습하며 정리한 내용입니다.
강의 자료에 포함된 일부 코드와 이미지를 참고하여 발췌·활용하였습니다.

자바 기본기를 제대로 다지고 싶으시다면, 아래 링크에서 강의를 확인해 보세요 

『김영한의 실전 자바 - 기본편』 보러 가기

본 게시물은 파트너스 활동의 일환으로 작성되었으며, 구매 시 소정의 수수료를 받을 수 있습니다.


접근 제어자

접근 제어자 종류

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

  1. private : 모든 외부 호출을 막는다.
  2. default(package-private) : 같은 패키지안에서 호출은 허용한다.
    • 접근 제어자를 명시하지 않으면 같은 패키지 안에서 호출을 허용하는 default 접근 제어자가 적용된다.
  3. protected : 같은 패키지안에서 호출은 허용하고, 패키지가 달라도 상속 관계의 호출은 허용한다.
  4. public : 모든 외부 호출을 허용한다.

순서대로 private 이 가장 많이 차단하고, public 이 가장 많이 허용한다.

접근 제어자의 핵심은 속성과 기능을 외부로부터 숨기는 것 이다.

접근 제어자 사용 - 필드, 메서드

다양한 상황에 따른 접근 제어자를 확인해보자.

AccessData

package access.a;
public class AccessData {
	 public int publicField;
	 int defaultField;
	 private int privateField;
	 
	 public void publicMethod() {
		 System.out.println("publicMethod 호출 "+ publicField);
	 }
	 
	 void defaultMethod() {
		 System.out.println("defaultMethod 호출 " + defaultField);
	 }
	 
	 private void privateMethod() {
		 System.out.println("privateMethod 호출 " + privateField);
	 }
	 
	 public void innerAccess() {
		 System.out.println("내부 호출");
		 publicField = 100;
		 defaultField = 200;
		 privateField = 300;
		 publicMethod();
		 defaultMethod();
		 privateMethod();
	 }
}

AccessData 클래스 특징은 아래와 같다.

  • 패키지 위치 : access.a
  • innerAccess() : 내부 호출을 보여준다.
    • 내부 호출 : 자기 자신에게 접근하는 것

이제 외부에서 이 클래스에 접근해보자.

AccessInnerMain

package access.a;
public class AccessInnerMain {
 public static void main(String[] args) {
	 AccessData data = new AccessData();
	 //public 호출 가능
	 data.publicField = 1;
	 data.publicMethod();
	 
	 //같은 패키지 default 호출 가능
	 data.defaultField = 2;
	 data.defaultMethod();
	 
	 //private 호출 불가
	 //data.privateField = 3;
	 //data.privateMethod();
	 data.innerAccess();
 }
}

AccessInnerMain 클래스의 특징은 아래와 같다.

  • public 은 모든 접근을 허용하기 때문에 필드, 메서드 모두 접근 가능하다.
  • default 는 같은 패키지에서 접근할 수 있기 때문에 AccessData 에 접근할 수 있다.
  • private 은 AccessData 내부에서만 접근할 수 있기 때문에, 호출 불가하다.
  • AccessData.innerAccess() 메서드는 public 이다. 따라서 외부에서 호출할 수 있다.
    • innerAccess() 메서드는 외부에서 호출되었지만, AccessData 에 포함되어 있기 때문에, 자신의 private 필드와 메서드에 접근할 수 있다.

AccessOuterMain

package access.b;
import access.a.AccessData;
public class AccessOuterMain {
 public static void main(String[] args) {
	 AccessData data = new AccessData();
	 //public 호출 가능
	 data.publicField = 1;
	 data.publicMethod();
	 
	 //다른 패키지 default 호출 불가
	 //data.defaultField = 2;
	 //data.defaultMethod();
	 
	 //private 호출 불가
	 //data.privateField = 3;
	 //data.privateMethod();
	 data.innerAccess();
 }
}

AccessOuterMain 특징은 아래와 같다.

  • 패키지 위치 : access.b
  • public 은 모든 접근을 허용하기 때문에 필드, 메서드 모두 접근 가능하다.
  • default 는 같은 패키지에서 접근할 수 있기 때문에 AccessData 에 접근할 수 없다.
  • private 은 AccessData 내부에서만 접근할 수 있기 때문에, 호출 불가하다.
  • AccessData.innerAccess() 메서드는 public 이다. 따라서 외부에서 호출할 수 있다.
    • innerAccess() 메서드는 외부에서 호출되었지만, AccessData 에 포함되어 있기 때문에, 자신의 private 필드와 메서드에 접근할 수 있다.

접근 제어자 사용 - 클래스

클래스 레벨의 접근 제어자는 public,default 만 사용할 수 있다. 또한 public 클래스는 반드시 파일명과 이름이 같아야 한다.

하나의 자바 파일에 public 클래스는 하나만 등장할 수 있지만, default 클래스는 무한정 만들 수 있다.

package access.a;
public class PublicClass {
 public static void main(String[] args) {
	 PublicClass publicClass = new PublicClass();
	 DefaultClass1 class1 = new DefaultClass1();
	 DefaultClass2 class2 = new DefaultClass2();
 }
}
class DefaultClass1 {
}
class DefaultClass2 {
}

패키지가 같으면 모두 접근할 수 있지만, 패키지가 다르면 public 클래스만 접근이 가능하다.


캡슐화(Encapsulation)

캡슐화는 객체 지향 프로그래밍의 중요한 개념 중 하나로, 데이터와 해당 데이터를 처리하는 메서드를 하나로 묶어서 외부에서의 접근을 제한하는 것을 말한다.

즉, 속성과 기능을 하나로 묶고, 외부에 꼭 필요한 기능만 노출하고 나머지는 모두 내부로 숨기는 것이다.

그럼 어떤 것을 숨기고 어떤 것을 노출해야 할까?

숨겨야 하는 것

데이터

객체에는 속성과 기능이 있다. 그 중 가장 필수로 숨겨야 하는 것은 속성(데이터) 이다. 객체 내부의 데이터를 외부에서 함부로 접근하게 두면, 클래스 안에서 데이터를 다루는 모든 로직을 무시하고 데이터를 변경할 수 있다.

객체의 데이터는 객체가 제공하는 기능인 메서드를 통해서 접근해야 한다.

기능

객체의 기능 중에서 외부에서 사용하지 않고 내부에서만 사용하는 기능들이 있는데, 이런 기능도 모두 감추는 것이 좋다.

즉, 데이터는 모두 숨기고, 기능은 필요한 기능만 노출하는 것이 캡슐화 이다.