4. 필드의 값을 초기화, 변경하는 방법
1. 클래스의 field에 private 키워드 적용
public class Mouse {
private int age;
private String name;
Mouse(int age, String name) {
this.age = age;
this.name = name;
}
}→ 접근 제어자의 개념을 활용하여 모든 필드에 직접 접근할 수 없도록 필드에 private을 적용
public class Main {
public static void main(String[] args) {
Mouse jerry = new Mouse(5, "제리");
jerry.age = 10; // Compile Error.
}
}→ private키워드를 적용하였기 때문에 외부에서는 jerry의 나이에 직접 접근하는 것이 불가능해짐
2. age 필드에 값이 변경될 수 있어야 하는 요구사항 발생
위 코드에서 현재 age 필드는 기본적으로 객체를 생성하는 시점에서 초기화를 하였지만
새롭게 추가된 기능 요구사항에 의해 객체가 생성된 이후에도 age 값이 변경될 수 있다고 할 경우?
→ ex. 한 해가 지나면 나이를 올려야 함
age 필드의 값을 변경하는 방법은 크게 2가지가 있음
2-1. age 필드에서 private 키워드를 다시 제거하여 필드의 값에 직접 접근하여 변경
public class Mouse {
// private int age;
int age;
Mouse(int age) {
this.age = age;
}
}public class Main {
public static void main(String[] args) {
Mouse jerry = new Mouse(5);
jerry.age = 10; // OK.
System.out.println(jerry.age); // 10
}
}이렇게 되면 어디에서든지 값의 변경이 가능해지게 되고, 프로그램의 동작이 예측하기 어려워짐
→ 캡슐화가 깨졌다고 볼 수 있음
2-2. age 필드의 값을 변경할 수 있는 별도의 메서드를 구현하여 접근하여 변경
age 필드를 파라미터로 전달받는 changeAge(int age)라는 별도의 메서드를 구현,
메서드 내부에서 파라미터로 전달받은 age값을 Mouse 클래스의 필드인 this.age에 초기화시킴
public class Mouse {
private int age;
Mouse(int age) {
this.age = age;
}
public void changeAge(int age) {
this.age = age;
System.out.println("age가" + this.age + "로 변경됨");
}
}결국 age 필드의 값을 변경할 수 있는 코드는 본질적으로 아래의 코드 한 줄인데,
this.age = ageMouse 클래스 내에서 생성자 메서드 외에 해당 코드가 작성된 부분이 없기 때문에,
문장(Statement)을 작성할 수 있는 별도의 새로운 영역을 구성하기 위해
별도의 메서드를 작성하여 age 필드의 값을 변경할 수 있는 코드를 추가 작성하면 됨
public void changeAge(int age) {
this.age = age;
}public class Main {
public static void main(String[] args) {
Mouse jerry = new Mouse(5);
jerry.changeAge(10); // jerry의 age가 10으로 변경됨
}
}3. 2-2 해결방식의 문제점?
문제 1. changeAge()는 [상속/7. 특성의 중복 - 두 번째] 에서 본 printMouse() vs toString()과 같이 메서드의 이름에 개발자의 주관이 들어가있음
문제 2. System.out.println()과 같은 출력문 코드가 없다면 jerry의 값이 5에서 10으로 바뀌었는지 어떻게 확인할 수 있을까?