[TIL 26/02/06](Java) 접근제어자와 캡슐화
2026. 2. 6. 18:03
접근 제어자(access modifier)

접근제어자란?

  • 클래스와 클래스의 멤버(생성자, 필드, 메서드)를 사용할 때 접근할 수 있는 범위를 지정하는 역할

 

1. 클래스의 접근 제어자

 

  • 클래스에 지정할 수 있는 접근 제어자는 publicdefault로 두 가지가 있다.
    • public : 패키지와 상관 없이 모든 클래스에서 접근 가능
    • default(생략) :  같은 패키지에 있는 클래스에서만 접근 가능

 

2. 클래스 멤버의 접근 제어자

 

  • 클래스 멤버에 지정할 수 있는 접근제어자는 public, private, protecteddefault로 네 가지가 있다.
    • public : 패키지와 상관 없이 모든 클래스에서 접근 가능
    • private(비공개) : 동일 클래스의 멤버들만 접근 가능
    • protected : 같은 패키지 내 모든 클래스와 상속 관계인 경우, 다른 패키지의 자식 클래스에서 접근 가능
    • default(생략) : 같은 패키지에 있는 클래스에서만 접근 가능
접근제어자 동일 클래스 동일 패키지 자손 클래스 전체
public O O O O
protected O O O X
default O O X X
private O X X X

 

 

 

 

 

캡슐화

 

캡슐화란?

  • private 접근제어자를 활용해서 데이터는 숨기고, 의도된 동작으로만 외부에 공개하는 것이다
  • 외부에서 private 멤버에 접근하기 위해서는 public 메서드를 활용해야 한다.

 

필요성

  • 외부의 잘못된 접근으로 인한 멤버의 변화나 의도치 않은 동작을 방지한다.
  • 유효하지 않은 값으로 직접 필드를 변경하려는 시도를 내부에서 valid 로직을 통해 필터링 할 수 있다.

 

활용법

  • 은닉하려는 필드나 메서드의 접근제어자를 private로 정의한다.
  • 다른 클래스에서 해당 필드나 메서드로 접근할 수 있는 public 메서드를 생성한다.
    • ex) getter, setter 메서드

 

예제

 

//캡슐화 예제 class MotorBike

public class MotorBike {

	//캡슐화
	private int speed;

	public int getSpeed() {
		return speed;
	}

	public void setSpeed(int speed) {
		if (speed > 0) {
			this.speed = speed;
		}
	}

	public void increaseSpeed(int howMuch) {
		setSpeed(this.speed + howMuch);
	}

	public void decreaseSpeed(int howMuch) {
		if (this.speed - howMuch < 0) {
			setSpeed(0);
		} else {
			setSpeed(this.speed - howMuch);
		}
	}

	void start() {
		System.out.println("Bike started");
	}

}

 

MotorBike 객체의 speed라는 필드 값 private 접근제어자를 사용해 캡슐화 해서 외부 클래스에서 직접 접근하지 못 하도록 설정했다.

 

외부 클래스에서는 public으로 공개된 메서드를 통해서만 speed 값에 접근할 수 있다.

 

이를 메인 메서드를 가지고 있는 Runner 클래스 코드로 보여주면

 

//접근 실패 예제

public class MotorBikeRunner {

	public static void main(String[] args) {
		MotorBike ducati = new MotorBike();
		MotorBike honda = new MotorBike();
        
		ducati.speed = 100;
}

 

외부 클래스에서 직접 ducati 객체의 speed 필드 값에 접근을 하니 오류가 뜬 모습이다.

 

오류 메시지에 MotorBike.speed is not visible 은 private 접근제어자에 의해 speed라는 필드 값이 가려져 있기 때문에 보이지 않는다는 의미이다.

 

다음은 MotorBike 클래스의 public 메서드를 호출해 접근한 예제이다

//접근 성공 예제

public class MotorBikeRunner {

	public static void main(String[] args) {
		MotorBike ducati = new MotorBike();
		MotorBike honda = new MotorBike();
        
		ducati.start();
		honda.start();
        
		System.out.println("==============");
		
		ducati.setSpeed(100);
		honda.setSpeed(80);
        
		System.out.println(ducati.getSpeed());
		System.out.println(honda.getSpeed());
        
		System.out.println("==============");
        
		ducati.increaseSpeed(50);
		honda.increaseSpeed(120);
        
		System.out.println(ducati.getSpeed());
		System.out.println(honda.getSpeed());
        
		System.out.println("==============");
        
		ducati.decreaseSpeed(25);
		honda.decreaseSpeed(23);
		
		System.out.println(ducati.getSpeed());
		System.out.println(honda.getSpeed());
        
		System.out.println("==============");
		}
		

}

 

동일 클래스의 public 메서드를 호출하여 성공적으로 캡슐화 되어 있는 멤버에 접근한 것을 확인할 수 있다.

 

느낀점

 

다 알고 있는 개념이라 생각했는데도 다시 회상하여 적으려고 하니 각 접근제어자의 공개범위 등 정확하게 생각나지 않은 것들도 있고, 실제로 외부 클래스에서 캡슐화된 멤버에 접근하면 어떻게 오류가 뜨는지 확인해 본 건 처음이라 좋은 경험이 된 것 같다.

 

내가 머리 속으로 이해하고 넘어가는 것과 내가 누군가에게 보여주고 설명하기 위해 이해하는 것은 많이 다르다는 걸 느꼈다.