가끔 인스턴스 필드들을 모아놓는 일 외에는 아무 목적도 없는 클래스를 작성할 때가 있다.
class Point {
public double x;
public double y;
}
→ 따라서, 객체 지향 프로그래머는 필드를 모두 private 으로 바꾸고 public 접근자(getter) 를 추가한다!
class Point {
private double x;
private double y;
public Point(final double x, final double y) {
this.x = x;
this.y = y;
}
**public double getX() {
return x;
}
public double getY() {
return y;
}
public void setX(final double x) {
this.x = x;
}
public void setY(final double y) {
this.y = y;
}**
}
public 클래스라면 위와 같은 방식을 사용하자.
하지만,
package-private,private중첩 클래스라면 데이터 필드를 노출한다 해도 문제가 없다.
클래스가 표현하려는 추상 개념만 올바르게 표현해주면 된다.
자바 플랫폼 라이브러리에도 public 클래스의 필드를 직접 노출한 사례가 종종 있다!
java.awt.package 패키지의 Point , Dimension
public클래스의 필드가 불변이라면 직접 노출할 때의 단점이 줄어들긴 하지만, 여전히 좋은 생각은 아니다.
API를 변경하지 않고는 표현 방식을 바꿀 수 없다.
필드를 읽을 때 부수 작업을 수행할 수 없다.
public final class Time {
private static final int HOURS_PER_DAY = 24;
private static final int MINUTES_PER_HOUR = 60;
**public final int hour;
public final int minute;**
public Time(final int hour, final int minute) {
if (hour < 0 || hour >= HOURS_PER_DAY) {
throw new IllegalArgumentException("시간: " + hour);
}
if (minute < 0 || minute >= MINUTES_PER_HOUR) {
throw new IllegalArgumentException("분: " + minute);
}
this.hour = hour;
this.minute = minute;
}
}
**
*public클래스는 절대 가변 필드를 직접 노출하지 말자. 불변 필드라면 노출해도 덜 위험하지만, 완전히 안심할 수는 없다.
하지만 package-private 클래스나 private 중첩 클래스라면 종종 필드를 노출하는 편이 나을 때도 있다.***