[자바 기초] 10강. 내 데이터는 소중하니까: 접근 제어자(private)와 캡슐화
지난 시간 복습과 이번 강의 목표
지난 시간까지 우리는 학생의 점수를 이렇게 다뤘습니다.
Student s1 = new Student();
s1.score = 100; // 문제없음
s1.score = -5000; // ??? (논리적으로 불가능한 점수지만 에러가 안 남)
누군가 실수로(혹은 고의로) 점수에 -5000을 넣으면 프로그램 전체가 꼬이게 됩니다.
하지만 int 변수는 그저 숫자 저장소라 이를 막을 힘이 없습니다.
그래서 등장한 개념이 **"중요한 데이터는 자물쇠로 잠그고(private), 허락된 관리자(Method)를 통해서만 접근하게 하자"**입니다. 이것을 **캡슐화(Encapsulation)**라고 합니다.
1. 접근 제어자: Public vs Private
자바에는 "누구까지 들어올 수 있냐"를 결정하는 키워드가 있습니다. 딱 두 개만 먼저 기억하세요.
public(공공의): "대문 활짝 열림." 누구나, 어디서든 접근 가능.private(사적인): "내 방문 잠금." 오직 이 클래스 안에서만 접근 가능. 다른 파일에서는 절대 못 건드림.
2. 캡슐화 적용하기 (Getter & Setter)
이제 Student.java를 수정해서 보안 시스템을 가동해 봅시다.
- 모든 필드(변수) 앞에
private을 붙여서 잠급니다. - 데이터를 넣고 뺄 수 있는 창구인 **메소드(Getter/Setter)**를 만듭니다.
// Student.java
public class Student {
// 1. 데이터 잠그기 (private)
// 이제 외부(Main)에서 s1.score로 직접 접근하면 에러가 납니다!
private String name;
private int score;
// 2. Setter (데이터 저장 담당자)
// 점수를 넣을 때 이상한 값이 아닌지 '검사'할 수 있습니다.
public void setScore(int score) {
if (score < 0 || score > 100) {
System.out.println("에러: 점수는 0~100 사이여야 합니다.");
return; // 값을 저장하지 않고 메소드 종료
}
this.score = score; // 검사 통과하면 진짜 변수에 저장 (this는 '내 것'이라는 뜻)
}
// 3. Getter (데이터 조회 담당자)
// 숨겨진 private 변수를 안전하게 꺼내줍니다.
public int getScore() {
return this.score;
}
// 이름(name)도 똑같이 만들어줍니다.
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
💡 this가 뭔가요?
this.score: 이 클래스가 가지고 있는 진짜 필드(멤버 변수)score: 매개변수로 들어온 임시 변수- 이름이 똑같아서 헷갈릴 때, "이건 내 필드야!"라고 알려주는 키워드입니다.
3. Main에서 사용해보기
이제 Main.java 코드를 수정해야 합니다. 예전처럼 점(. ) 찍고 바로 접근하려고 하면 빨간 줄(에러)이 뜹니다.
// Main.java
public class Main {
public static void main(String[] args) {
Student s1 = new Student();
// s1.score = -50; // 에러 발생! (private이라 접근 불가)
// 올바른 사용법: Setter를 이용한다
System.out.println("--- 1. 이상한 점수 넣기 ---");
s1.setScore(-50); // Setter 내부의 if문이 작동해서 막아줌
System.out.println("--- 2. 정상 점수 넣기 ---");
s1.setScore(95); // 이건 통과
// 값 꺼내기: Getter를 이용한다
System.out.println("학생 점수: " + s1.getScore() + "점");
}
}
실행 결과
--- 1. 이상한 점수 넣기 ---
에러: 점수는 0~100 사이여야 합니다.
--- 2. 정상 점수 넣기 ---
학생 점수: 95점
4. 왜 이렇게 귀찮게 하나요?
코드가 길어지는데 굳이 이렇게 하는 이유는 명확합니다.
- 데이터 보호: 무효한 값(음수 점수, 나이 5000살)이 들어가는 것을 원천 봉쇄할 수 있습니다.
- 유지 보수: 나중에 "점수를 조회할 때마다 로그를 남겨라"라는 지시가 내려오면,
getScore()메소드 하나만 수정하면 됩니다. (필드에 직접 접근하는 방식이었다면 수백 군데 코드를 다 고쳐야 했겠죠?)
5. 꿀팁: 인텔리제이 자동완성
Getter와 Setter를 일일이 치는 건 손가락이 아픕니다.
인텔리제이에서는 Alt + Insert (맥은 Cmd + N)를 누르고 **[Getter and Setter]**를 선택하면, 마법처럼 코드를 자동으로 만들어줍니다. 실무에서는 다 이렇게 짭니다.
6. 마무리
이제 여러분의 객체는 데이터를 안전하게 지킬 수 있는 **'보안 시스템'**까지 갖췄습니다. 하지만 여전히 귀찮은 점이 하나 있습니다.
Student s1 = new Student();
s1.setName("철수");
s1.setScore(90);
학생을 만들자마자 이름과 점수를 세팅해야 하는데, 이걸 매번 3줄씩 써야 할까요? "학생이 태어날 때(new)부터 이름과 점수를 가지고 태어나게 할 순 없을까?"
다음 **[11강]**에서는 객체 생성의 마법사, **생성자(Constructor)**에 대해 배워보겠습니다. new Student("철수", 90); 한 줄로 끝내는 법을 알려드립니다.