캡슐화는 특정 객체 안에 관련된 속성과 기능을 하나의 캡슐처럼 만들어 데이터를 외부로부터 보호하는 것을 말합니다.
캡슐화를 함으로서
가 이루어지게됩니다. 즉, 캡슐화의 큰 장점은 정보 은닉(data hiding)에 있다고 할 수 있습니다.
외부로부터의 객체의 속성과 기능을 함부로 변경되지 못하게 막고, 데이터가 변경되더라도 다른 객체에 영향을 주지 않게 만들어 독립성을 확보할 수 있습니다. 또한, 유지보수와 코드 확장 시 속성과 기능이 독립되어있기에 오류의 범위를 최소화 할 수 있습니다.
자바 프로그래밍에서 제어자는 클래스, 필드, 메서드, 생성자 등에 부가적인 의미를 부여하는 키워드입니다.
제어자는 접근제어자와 기타 제어자로 나뉩니다.
접근 제어자를 사용함으로서 클래스 외부로의 불필요한 데이터 노출을 방지 할 수 있고, 내부의 데이터가 함부로 변경되는 행위를 막을 수 있습니다.
자바의 접근 제어자로는 다음의 4가지가 있습니다.
접근 제어자 | 제한 범위 |
---|---|
private | 동일 클래스에서만 접근 가능 |
default | 동일 패키지 내에서만 접근 가능 |
protected | 동일 패키지 + 다른 패키지 하위 클래스에서 접근 가능 |
public | 접근 제한 없음 |
접근 제한 범위로 표현하자면
public > protected > default > private
만약 변수명 앞에 아무런 접근제어자가 없는 경우 default
로 동작하게 됩니다.
예시를 한번 보겠습니다!
package package1; // 패키지명 package1
//파일명: Parent.java
class Test { // Test 클래스의 접근 제어자는 default
public static void main(String[] args) {
Parent p = new Parent();
// System.out.println(p.a); // 동일 클래스가 아니기 때문에 에러발생!
System.out.println(p.b);
System.out.println(p.c);
System.out.println(p.d);
}
}
public class Parent { // Parent 클래스의 접근 제어자는 public
private int a = 1; // a,b,c,d에 각각 private, default, protected, public 접근제어자 지정
int b = 2;
protected int c = 3;
public int d = 4;
public void printEach() { // 동일 클래스이기 때문에 에러발생하지 않음
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
}
}
// 출력값
2
3
4
private
로 지정된 int a
는 pirntEach
메서드에선 같은 클래스에 정의된 메서드이기 때문에 에러가 발생하지 않습니다 하지만 Test
클래스는 외부의 클래스입니다. 접근이 불가함으로 사용 할 수도 읽을 수도 없어 에러가 발생하게 됩니다.
그렇다면 private
된 클래스와 변수는 사용할 수 없는 걸까요?? 이를 이용하기 위해getter, setter
를 알아봅시다.
getter와 setter는 private
가 포함되어있는 객체의 변수에 값을 수정하거나, 불러올 때 사용되게됩니다.
public class GetterSetterTest {
public static void main(String[] args) {
Worker w = new Worker();
w.setName("홍길동");
w.setAge(30);
w.setId(5);
String name = w.getName();
System.out.println("근로자의 이름은 " + name);
int age = w.getAge();
System.out.println("근로자의 나이는 " + age);
int id = w.getId();
System.out.println("근로자의 ID는 " + id);
}
}
class Worker {
private String name; // 변수의 은닉화. 외부로부터 접근 불가
private int age;
private int id;
public String getName() { // 멤버변수의 값
return name;
}
public void setName(String name) { // 멤버변수의 값 변경
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age < 1) return;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
// 출력값
근로자의 이름은 홍길동
근로자의 나이는 30
근로자의 ID는 5
setter
메서드는 외부에서 접근하여 데이터 값을 변경하게 해주고 일반적으로 메서드명에 set-
을 붙여서 정의해줍니다.
getter
는 설정된 변수 값을 읽어오는 데 사용되는 메서드입니다. 경우따라 변수에 저장된 값을 사용할 수 있도록 가공한 후에 외부로 전달해 줄 수 있습니다. 일반적으로 메서드명에 get-
을 붙여 정의합니다.
이로서 필드에 정의된 변수들이 외부에 직접 노출되지 않아 접근하기 위해 우회를 하여 사용되게 됩니다!